|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
Contents
IntroductionMany of us from time to time have struggled with configuring log4net. I know that in just about every application that I have worked on, I have taken a log4net configuration file, copied it and changed it to my liking. Well after some research and fiddling around with the configuration options available in log4net, I have come up with some interesting discoveries.The first is that we can easily create separate log file / appenders for each class, assembly or even namespace if we want. Before I give you the answer, I want to tell you a little bit about the log4net library. Definitionslog4net is essentially made up of six objects:log4net, log4net.Appender,
log4net.Config, log4net.Filter, log4net.Layout
and log4net.Repository. Here are there definitions.
How the objects relate to each other.Each repository has oneLogManager. Each LogManager has
one or more Loggers. Each logger has one or more Appenders. Each Appender has one
or more filters and one layout.
The ConfigurationThe easiest and most flexible way to configure log4net is with XML files. log4net provides a configuration reader for XML files in thelog4net.Config.XmlConfiguratorclass.
The XML file is comprised of 2 parts (that I know of). The first is one or more
Appender definitions, the second defines the loggers and what Appender definitions
to a logger in the repository.
The
The
Appender ConfigurationEach appender has different configuration options. The XML element looks similar to this.<appender name="rootRollingFile" type="log4net.Appender.RollingFileAppender,log4net">
<threshold value="ALL"/>
<param name="File" value="logs/MasterLog"/>
<param name="AppendToFile" value="true"/>
<param name="RollingStyle" value="Date"/>
<param name="DatePattern" value=".yyyy.MM.dd.'log'"/>
<param name="StaticLogFileName" value="false"/>
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%date [%-5thread] %-5level %logger - %message%newline %exception"/>
</layout>
</appender>
The
The
Assigning Appenders to LoggersThere are two elements that are used for assigning Appenders to loggers, root and logger. With each of these elements you can assign two childelements,
level and appender-ref.
The <level> element tells log4net what log messages will be sent
to this appender, this is the equivalent to the <threshold> element
on the appender. The <appender-ref> element is used to assign
the appender to the specific logger. The format of the element is <appender-ref
ref="nameOfAppender" /> where the nameOfAppender is the name
that was specified in the name attribute of the <appender> element.When the <root> element is used, all logging message for the
LogManager / logging Repository will be written to these appenders.The <logger> element has one attribute, name, the name attribute
can be a namespace, class, or object name that you want to attach a special appender
to. This is how we are going to be able to attach a different appender for each
class or library.<root>
<level value="ALL"/>
<appender-ref ref="rootTrace"/>
<appender-ref ref="rootConsole"/>
<appender-ref ref="rootRollingFile"/>
<appender-ref ref="rootEventLog"/>
</root>
<logger name="MyCompany">
<level value="WARN" />
<appender-ref ref="MyCompany_rollingFile" />
</logger>
<logger name="MyCompany.MultipleClasses">
<level value="WARN" />
<appender-ref ref="MyCompany_Multiple_rollingFile" />
</logger>
<logger name="MyCompany.MultipleClasses.Class1">
<level value="DEBUG" />
<appender-ref ref="class1File" />
</logger>
<logger name="MyCompany.MultipleClasses.Class2">
<level value="DEBUG" />
<appender-ref ref="class2File" />
</logger>
<logger name="MyCompany.MultipleClasses.Class3">
<level value="DEBUG" />
<appender-ref ref="class3File" />
</logger>
<logger name="MyCompany.Library1.MyFirstClass">
<level value="DEBUG" />
<appender-ref ref="lib1_MyFirstClass_File" />
</logger>
<logger name="MyCompany.Library2.MySecondClass">
<level value="DEBUG" />
<appender-ref ref="lib2_MySecondClass_File" />
</logger>
<logger name="MyCompany.Library2.MyThirdClass">
<level value="DEBUG" />
<appender-ref ref="lib2_MyThirdClass_File" />
</logger>
With this in mind, by looking at the configuration above, we can determine the following.
SummaryI know this was a lot to digest, if you have any questions, thoughts or comments on this article, please feel free to let me know.ReferencesHistory
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||