Creating C# Logger with CsharpGears



The Need of Logger for C#
Loggers come in handy when one wishes to trace the execution of his program. These pieces of code make life much easier when it comes to maintaining the application code error free. That is because with logging capabilities, the developer is able to track every time an unusual event occurs. Then it will be easy to determine where the code needs more attention, whether it includes refactoring, bugs or something else.
There are loggers for C#, they are not something new. But what they often lack, is known as ease-of-use. Here could fall Log4Net and other classes that could be found accross the Web. Often, developer needs a simple logger, some code that will get the job done when an exception is thrown. 
Therefore I have decided to write flexible C# classes that will still be extremely simple to use, flexible by design, and will give the developer control of the log level.(Log levels are an important aspect of the loggers, as they give the power to control which events will enter the log, and which will be left out.
The Database Logger in C#
The Logger classes in the CsharpGears Framework are organized in the following way:

 
 There exists a class named LoggerBase which is abstract and it also implements the ILogger interface. From it DbLogger class is derived, and that is the main class we are going to use. There are also SqlServerDbLoggerProvider class which configures the DbLogger so that it creates the needed tables and stored procedures in the database. These logger classes communicate with LogMessages. There is a generic LogMessage
from which other LogMessages are derived. For each log level, there exists an appropriate message.


So, let's show an example of the usage of the the C# logger.
/* Set up configuration for the logger */
string DbProvider = "System.Data.SqlClient";
            string ConnectionString = "...";

            /* Create the logger */
            ILogger Logger = new DbLogger(DbProvider,ConnectionString);
            Configuration.LogLevel = LogLevel.ERROR;
            /* Create log messages */
            ILogMessage Message = new LogMessage("Message Content: Error", "SYSTEM",
LogLevel.INFO);
            ILogMessage InfoMessage = new InfoLogMessage("Info log message", "SYSTEM");
            ILogMessage ErrorMessage = new ErrorLogMessage("Fatal error", "SYSTEM");
            ILogMessage AllMessage = new AllLogMessage("All log message", "SYSTEM");

            /* Append the messages */
            Logger.Append(Message);
            Logger.Append(InfoMessage);
            Logger.Append(ErrorMessage);
            Logger.Append(AllMessage);

            /* Retrieve all messages from the log */
            List<LogMessage> LogContent = Logger.ReadLog();

            /* Retrieve the messages from today */
            List<LogMessage> TodaysLogContent = Logger.ReadLogByDate(DateTime.Now);

            /* Print the log messages from today */
            foreach (LogMessage message in TodaysLogContent) 
            {
                Console.WriteLine(message.Message + " " + message.UserName + " "
+ message.Date + "\n");
            }
As you can see, you only need to configure the logger for the database provider and the connection string - and you are ready to go. When you want to append a message, you only need to create the appropriate message object - you can either use the interface notation, or create the message type directly, by creating a log message of the specific type. Then you need to invoke the Append() method. For retrieval of the messages from the logger, you need to invoke the method ReadLog(), or you can read the messages from today. (In the future version, I will add an opportunity to read according to the log level). And then, you will get a generic C# list of Log messages. In case you were wondering, this utilizes the DatabaseEntity classes, discussed in my previous post about database access with the CsharpGears framework.
If you have any questions about using this logger, feel free to ask. As you can see, it is very simple to use, and it abstracts most of the annoying things when developing logger classes in C#.

5 comments:

dotnetgeeks said...

Hi seesharpgears.
Thanks for your appreciation and detailed feedback. My Logger class is very basic in nature and can be used to log the exception messages that arise from the C# code. I believe that somebody who uses this class gets a basic startup class so that he can extend it to his own requirements.

I went through through post at http://seesharpgears.blogspot.com/2009/09/creating-c-logger-with-csharpgears.html
This is one of the best examples of C# code and logging I have ever seen. This logger will be very usefulin a application when you want more logging information from some areas, and less from others and the programmer has to facilitate this by allowing different logging levels for different loggers. Your logger is the best fit in that case.
Your work is great.
Thanks for adding the extra kilobytes bytes in my knowledge….

Raju.M said...

i think this is good example of error logging in OOPs Concepts. i wrote a simple error logging function to log our errors in Text file check this also C# Error Logging

SeeSharpWriter said...

Your logging function is clean and simple, I commented it today earlier. I like your blog in general, whould you like us to exchange links between blogs ? Increased traffic is a benefit for both of us...

Anonymous said...

IT is indeed a very good example. But In my situation, I have to use a file to log and i would like to write logs of different component into different folders..In this case this wont work isnt it? since the configuration is static. Also if multiple threads are trying to write to the same file, the logging will fail..
What do you sugeest I do for my scenario?

SeeSharpWriter said...

You point out the pros and cons of logging to files: if you decide to use files for logging - using it in multiple threads will cause you headaches.

This is the main reason I have developed a Database logger in the first place.
The configuration is not static as long as you decide to use database.

However, if you really want to use file as logger storage, you can simply derive from my class LoggerBase or implement interface ILogger.

If you have any more questions, feel free to ask.

Post a Comment