Configuring log4net Programmatically
Sometimes we are in the mood to code as quickly as possible without getting into configuration files. Normally, that happens when we are trying to test something. In that case, you have another way to do the configuration. All of the long configuration files that we saw in the previous section can be defined programmatically using a few lines of code. See the following code:
// using a FileAppender with a PatternLayout
log4net.Config.BasicConfigurator.Configure(
new log4net.Appender.FileAppender(
new log4net.Layout.PatternLayout("%d
[%t]%-5p %c [%x] <%X{auth}> - %m%n"),"testfile.log"));
// using a FileAppender with an XMLLayout
log4net.Config.BasicConfigurator.Configure(
new log4net.Appender.FileAppender(
new log4net.Layout.XMLLayout(),"testfile.xml"));
// using a ConsoleAppender with a PatternLayout
log4net.Config.BasicConfigurator.Configure(
new log4net.Appender.ConsoleAppender(
new log4net.Layout.PatternLayout("%d
[%t] %-5p %c [%x] <%X{abc}> - %m%n")));
/
/ using a ConsoleAppender with a SimpleLayout
log4net.Config.BasicConfigurator.Configure(
new log4net.Appender.ConsoleAppender(new
log4net.Layout.SimpleLayout()));
You can see that while it is easy to code here, you can't configure settings for individual loggers. All of the settings that are defined here are applied to the root logger.
The log4net.Config.BasicConfigurator class uses its static Configure method
to set an Appender object. The Appender constructor, in turn, requires the Layout
object. Other parameters are respective to the type of component you are
using.
You can also use BasicConfigurator.Configure() without any parameter to show
the output using ConsoleAppender with a specific PatternLayout, as follows:
Code
log4net.Config.BasicConfigurator.Configure();
Output
0 [1688] DEBUG log1 A B C - Test
20 [1688] INFO log1 A B C - Test
Now that the application is configured, you can write the logging code, as shown in the previous section.
Logging in a Multithreaded Application
One of the most noticeable features of log4net is its support for multithreaded
applications. This helps you in scenarios where your application is simultaneously
accessed by multiple clients. Therefore, to trace requests from different clients,
you need a mechanism to identify different clients in your logging framework. This
mechanism is provided in log4net through two different methods, Nested Diagnostic Context (NDC) and Mapped Diagnostic Context (MDC).
Nested Diagnostic Context (NDC)
NDC uses a stack per thread to identify different clients. The stack's
Push() method is used to set any value that identifies the client. It is
the developer's responsibility to put in a unique value for each client.
To constrain NDC into a certain block of code, the developer can use the "using"
statement to make his task easier, because it automatically pops the respective
value from the stack.
using(log4net.NDC.Push("clientid")
{
log.Info("message"); // output: "clientid – message"
} // here the value is popped from the stack
NDC class can also be used without the using block.
log4net.NDC.Push("clientid"); // context started here
…. // put client aware log messages here
log4net.NDC.Pop(); // context ended here
The framework provides a special conversion term, "%x," to display
the NDC value on the stack using the PatternLayout.
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%x" />
</layout>
If you push multiple values into the stack, then all of those values are concatenated in the output.
If you are using the XMLLayout class as the layout for your appender, then you
automatically have the NDC value as a CDATA section inside of the <log4net:NDC>
tag.
<log4net:NDC><![CDATA[A B C]]></log4net:NDC>
Mapped Diagnostic Context (MDC)
Instead of using a stack, the MDC class uses a map to store individual user
information. It could not be used inside of the using block; therefore, we have to
use it in a Get()/Set() combination to manipulate the map values. Values
can be deleted from the map using the Remove() method. Similar to NDC, MDC also
works on a per-thread model, and requires the conversion term inside of
the pattern string, if you are using the PatternLayout. For MDC, the term is "%X"
(capital X) with the key concatenated to the character in curly braces. In the
following example, %X{clientid} is replaced with the value for the key clientid.
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern"
value="%X{clientid}"
/>
</layout>
Logging in ASP.NET
Using log4net with ASP.NET is similar to the other applications.
Here, you can put the configuration attributes inside of the global.asax file, as well
as in any of the WebForms files. Putting it in global.asax is far easier
to remember.
More with log4net
There is a lot left to explore in the log4net framework. New features are
also integrating into the framework quite frequently. Once you get started using
the information provided in this article, the next step would be to experiment
with the samples provided with the sources. In order to follow the updates on
the framework, I'll try to use the forum to post any changes. I would like to
acknowledge Nicko Cadell from www.Neoworks.com
for reviewing this article and helping me with some technical details.
Resources
log4net– log4net.sourceforge.net- "How
to configure
log4netwith WebServices" - Complete Features List: log4net.sourceforge.net/release/1.2.0.30507/doc/features.html
- Release Notes: log4net.sourceforge.net/release/1.2.0.30507/releasenotes.html
- Appenders List and Example Configurations: log4net.sourceforge.net/release/1.2.0.30507/doc/manual/example-config-appender.html
- Framework Support Document: log4net.sourceforge.net/release/1.2.0.30507/doc/manual/framework-support.html
- FAQ: log4net.sourceforge.net/release/latest/doc/manual/faq.html
- User List @ sourceforge: log4net-users@lists.sourceforge.net
log4netmanual: log4net.sourceforge.net/release/latest/doc/manual/introduction.html
Return to ONDotnet.com

