Click here to Skip to main content
Click here to Skip to main content
Go to top

An Introduction to the log4net logging library, using C# - Part 2

, 12 Sep 2004
Rate this:
Please Sign up or sign in to vote.
An article describing more basic use of the log4net library.

Introduction

In my previous article, I discussed the basics of the log4net logging package. I gave an overview of the 5 levels of logging that the library provides, and examples of the different type of appenders that can be used for outputting data to your logs. In this article, I'd like to give some information on how to use log4net effectively.

Specifying different logging levels for different modules

Sometimes within your application, you will want more logging information from some areas, and less from others. Log4net facilitates this by allowing different logging levels for different loggers. An example of this is shown in LogTest3 and LogTest4.

using log4net;
using log4net.Config;

public class LogTest3
{
    private static readonly ILog logger = 
            LogManager.GetLogger(typeof(LogTest3));
    
    static LogTest3()
    {
        DOMConfigurator.Configure();
    }

    static void Main(string[] args)
    {
        LogTest3 log3 = new LogTest3();
        log3.DoLogging();
        LogTest4 log4 = new LogTest4();
        log4.DoLogging();
    }
    
    public void DoLogging()
    {
        logger.Debug("Here is a debug log from LogTest3.");
        logger.Info("... and an Info log from LogTest3.");
    }
}

public class LogTest4
{
    private static readonly ILog logger = 
            LogManager.GetLogger(typeof(LogTest4));
    
    static LogTest4()
    {
        DOMConfigurator.Configure();
    }

    public void DoLogging()
    {
        logger.Debug("Here is a debug log from LogTest4.");
        logger.Info("... and an Info log from LogTest4.");
    }

}

The configuration file for LogTest3 has the following lines of interest:

<root>
    <level value="FATAL" />
    <appender-ref ref="ConsoleAppender" />
</root>

<logger name="LogTest3">
    <level value="DEBUG" />
</logger>

<logger name="LogTest4">
    <level value="INFO" />
</logger>
</pre>

Within this XML fragment, we can see that the root logging level is set to "FATAL". That means that only FATAL error messages are logged. We can see however that this is overridden for LogTest3 and LogTest4 to the "DEBUG" and "INFO" levels accordingly. When we run this application, we will see then that LogTest3 logs everything from DEBUG level whereas LogTest4 logs everything from INFO level onwards.

2004-09-12 21:45:51,546 [1060] DEBUG LogTest3 - Here is a debug log from LogTest3.
2004-09-12 21:45:51,546 [1060] INFO  LogTest3 - ... and an Info log from LogTest3.
2004-09-12 21:45:51,546 [1060] INFO  LogTest4 - ... and an Info log from LogTest4.

Using this technique of specifying different log levels for different parts of your application gives you a great flexibility.

Should I log or not?

In general, the more logging you have, the greater flexibility you have and the easier it is to find out what's going wrong with your program. Don't get me wrong, logging is no substitute for debugging your program thoroughly, but there's always the case when you have deployed your application and you want to know exactly what's going on.

Sometimes, the cost of logging can be expensive, particularly when performance of your application is paramount (imagine logging every DEBUG statement to a database). Obviously, the first thing to do here, is turn down the logging level so that only the relevant information is produced (e.g., WARNINGs and above). This is a good start, but what if the cost of construction of the logging message is great (e.g., you have an expensive .ToString() method)?

logger.Debug("Expensive object value="+ExpensiveObject.ToString());

The ILog interface (of which all your loggers are implemented) provides a set of methods that enable you to check if a particular logging level is being used. These methods are shown below:

bool IsDebugEnabled();
bool IsInfoEnabled();
bool IsWarnEnabled();
bool IsErrorEnabled();
bool IsFatalEnabled();

Using these functions, we can now change our logging code for the expensive object to:

if (logger.IsDebugEnabled())
{
    logger.Debug("Expensive object value="+ExpensiveObject.ToString());
}

Completely removing logging

If you are completely happy with your application and you want to turn off logging completely, you can do this by setting the logging threshold to "OFF" for any/all your appenders, as shown below:

<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
    <threshold value="OFF" />
    <layout type="log4net.Layout.PatternLayout">
        <param name="Header" value="[Header]\r\n" />
        <param name="Footer" value="[Footer]\r\n" />
        <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
    </layout>
</appender>

The threshold can also be set to one of DEBUG, WARN, INFO etc. to set the threshold for the specified appender irrespective of the logger being used.

That's all

That's the end of the brief introduction to logging using log4net. I hope you've enjoyed these articles, and I hope I've convinced you that logging is worthwhile and fun!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

David Salter
Web Developer
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
Questioncan i add the <threshold value="OFF" /> without building Pinmembertikva3331-Jul-11 23:15 
Generalgood example PinmemberDonsw24-Oct-10 10:36 
GeneralMy vote of 4 PinmemberDhrubajit13-Jul-10 2:30 
GeneralRe: My vote of 4 PinmentorTrollslayer5-Nov-10 10:07 
GeneralMy vote of 1 PinmemberDhrubajit13-Jul-10 2:30 
GeneralMy vote of 1 PinmemberDhrubajit13-Jul-10 2:29 
GeneralRe: My vote of 1 Pinmemberomonney28-Oct-10 2:05 
Questionwhere is the log output? Pinmemberavi91116-Jun-10 22:37 
QuestionWhy private static readonly ?? PinmemberAmitB198216-Mar-10 20:31 
GeneralThank you for the tutorials PinmemberDirk Voss19-Mar-09 6:57 
Generaldifferent loggers for different files PinmemberSh Usman Shakeel4-Apr-07 22:26 
GeneralRe: different loggers for different files PinmemberJoeSharp4-Apr-07 22:45 
hi
 
try this
 
logger name="Test"
level value="DEBUG"
appender-ref ref="HealthAppender"
appender-ref ref="CommandMessageAppender"
logger
 
regards
GeneralRe: different loggers for different files PinmemberSh Usman Shakeel8-Apr-07 20:08 
GeneralXML Appender Pinsussdanielmgv12-Jul-05 1:57 
GeneralLog4Net Configuration setting PinmemberJeyaprakash,R.4-Jul-05 0:20 
GeneralDavey let's update this to have ADONetAppeder as well PinmemberNirosh25-Apr-05 19:02 
GeneralADONetAppender PinmemberNirosh30-Mar-05 0:15 
GeneralNeed help Pinmemberenjoycrack18-Jan-05 0:20 
GeneralRe: Need help PinmemberDavey18-Jan-05 8:38 
GeneralRe: Need help Pinmemberenjoycrack18-Jan-05 14:52 
GeneralRe: Need help PinmemberDavey19-Jan-05 8:07 
GeneralRe: Need help Pinmemberenjoycrack19-Jan-05 14:43 
GeneralUsing attribute on assembly to specify configurator PinmemberDoug de la Torre15-Sep-04 11:21 
GeneralRe: Using attribute on assembly to specify configurator PinmemberDavey16-Sep-04 10:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 12 Sep 2004
Article Copyright 2004 by David Salter
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid