log 4 net

14
Log4net Log4net Jayakrishna Janapareddy

Upload: jayakrishna-janapareddy

Post on 24-Oct-2014

203 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Log 4 Net

Log4net

Log4net Jayakrishna Janapareddy

Page 2: Log 4 Net

Log4net

2 JayaKrishna Janapareddy

INTRODUCTION

One of the logging tools out there for .NET is log4net. This software is gold standard for how

logging is done. It is simple, powerful and extensible.

Log4net is used for debugging or for tracing purpose.

Log4net is from the Apache Software Foundation.

There are 3 parts for log4net: Configuration, setup and the call. Configuration is typically done in

App.config or web.config. Setup is basically a couple of lines of housekeeping that need to be

called in order to setup and instantiate a connection to the logger.

There are 7 logging levels, 5 of which can be called in code. They are as follows:

o OFF – nothing gets logged (cannot be called)

o FATAL

o ERROR

o WARN

o INFO

o DEBUG

o ALL- Everything will be logged (cannot be called).

These above levels will be used multiple times, both in your code as well as in the config file.

Log4net defines above 5 security levels as:

o DEBUG – fine grained statements concerning program state, typically used for

debugging.

o INFO – informational statements concerning program state, representing program

events or behavior tracking.

o WARN – statements that describe potentially harmful events or states in the program.

o ERROR – statements that describe non-fatal errors in the application; this level is used

quite often for logging handled exceptions.

o FATAL – statements representing the most severe of error conditions, assumedly

resulting in program termination.

Page 3: Log 4 Net

Log4net

3 JayaKrishna Janapareddy

CONFIGURATION

There are few pieces of information that needed to be placed in the config file in order to make

it work properly with log4net.

ConfigSections: The declaration of Log4net configuration section is mandatory. <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> </configSections>

Appender: An appender is an object that persists your log messages someplace. It specifies

where the information will be logged, how it will be logged, and under what circumstances the

information will be logged. While each appender has different parameters based upon where

the data will be going, there are some common elements. The first is the name and the type of

the appender. <appender name="ConsoleAppender"

type="log4net.Appender.ConsoleAppender">

Some of the common appenders are:

o Console Appender: It writes to the output window or command window if we use a

console application. <appender name="ConsoleAppender"

type="log4net.Appender.ConsoleAppender">

</appender>

o File Appender: The appender will write to a text file. The big difference to note here are

that we have to specify the name of the text file, we have to specify that we have to

append to the file, and have to specify that File appender should use the minimal lock

which will make the file usable by multiple appenders. <appender name="FileAppender"

type="log4net.Appender.FileAppender">

<file value="mylogfile.txt" />

<appendToFile value="true" />

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

</appender>

Common configuration attributes for the FileAppender:

file: the full or relative path to the log file.

appendToFile: Boolean indicating whether the log file should be appended

(true) or overwritten (false). If false, the file overwrite occurs during log4net

initialization. If unspecified, the log file is appended.

immediateFlush: Boolean indicating whether to flush the log file TextWriter

after each log message is written. The default is true (flush each message after

its written);

lockingModel: allows control over the log file locking strategy. This can be

either "log4net.Appender.FileAppender+MinimalLock" to allow for loose file

locking or "log4net.Appender.FileAppender+ExclusiveLock" to lock the file

during program execution. The default is the exclusive lock, and I highly

recommend you stick with that lock for performance reasons.

Page 4: Log 4 Net

Log4net

4 JayaKrishna Janapareddy

o Rolling File Appender: This is an appender that should be used in place of File appender

whenever possible. The purpose of this appender is to perform the same functions as

the file appender but with additional option to only store a certain amount of data

before starting a new log file. This way, we need not worry about the logs on a system

filling up over time. <appender name="RollingFileAppender"

type="log4net.Appender.RollingFileAppender">

<file value="mylogfile.txt" />

<appendToFile value="true" />

<rollingStyle value="Size" />

<maxSizeRollBackups value="5" />

<maximumFileSize value="10MB" />

<staticLogFileName value="true" />

</appender>

RollingFileAppender includes these parameters: rollingStyle: this controls how log files are "rolled," and can be one of the

following values:

o Once: the log file is rolled every time log4net is initialized (typically at

application startup);

o Size: the log file is rolled once it breaches a certain size;

o Date: the log file is rolled based on the current date;

o Composite: the log file is rolled based on size constraints and the

current date;

maximumFileSize: the size cap on the log file. This is an expression of size in the

form of "#(KB|MB|GB)". For instance, "100KB" or "10MB";

maxSizeRollBackups: the maximum number of rolled log file backups to

maintain when rollingStyle is SIZE; when rollingStyle is COMPOSITE, this

indicates the maximum number of roll-offs maintained per day; this property

has no effect when rollingStyle is ONCE or DATE;

datePattern: the date pattern used to roll files based on date. The value of this

parameter needs to adhere to the format used by the SimpleDateFormatter

class;

staticLogFileName: a bit of a misnomer - when true this setting indicates

whether log4net should actively write logs to the configured file (log-file.txt in

our example configuration) and maintain rolling backups by copy. When false,

this setting indicates that log4net will actively log to the latest roll-off file (e.g.,

log-file1.txt, log-file2.txt, log-file3.txt, etc);

countDirection: indicates how roll-off file numbering is managed. When this

parameter is >= 0, the newest log file will have the largest number; e.g., log-

file.txt.5 will be newer than log-file.txt.4. When countDirection < 0, the newest

log file will have the lowest number; e.g., log-file.txt.1 will be newer than log-

file.txt.2. If unspecified, countDirection defaults to (-1);

Page 5: Log 4 Net

Log4net

5 JayaKrishna Janapareddy

o ADO.NET Appender: This is the tricky one. This specific example writes to SQL, but you

can write to just about any database you want using this pattern. Note that the

connectionType is basically a connection string, so modifying it is simple. The

commandText specified is a simple query. You can modify it to any type of INSERT

query that you want <appender name="AdoNetAppender"

type="log4net.Appender.AdoNetAppender">

<bufferSize value="100" />

<connectionType value="System.Data.SqlClient.SqlConnection,

System.Data, Version=1.0.3300.0, Culture=neutral,

PublicKeyToken=b77a5c561934e089" />

<connectionString value="data source= [database server];

initial catalog= [database name]; integrated security=false;

persist security info=True; User

ID=[user];Password=[password]" />

<commandText value="INSERT INTO Log

([Date],[Thread],[Level],[Logger],

[Message],[Exception]) VALUES (@log_date, @thread,

@log_level, @logger, @message, @exception)" />

<parameter>

<parameterName value="@log_date" />

<dbType value="DateTime" />

<layout type="log4net.Layout.RawTimeStampLayout" />

</parameter>

<parameter>

<parameterName value="@thread" />

<dbType value="String" />

<size value="255" />

<layout type="log4net.Layout.PatternLayout">

<conversionPattern value="%thread" />

</layout>

</parameter>

<parameter>

<parameterName value="@log_level" />

<dbType value="String" />

<size value="50" />

<layout type="log4net.Layout.PatternLayout">

<conversionPattern value="%level" />

</layout>

</parameter>

<parameter>

<parameterName value="@logger" />

<dbType value="String" />

<size value="255" />

<layout type="log4net.Layout.PatternLayout">

<conversionPattern value="%logger" />

</layout>

</parameter>

Page 6: Log 4 Net

Log4net

6 JayaKrishna Janapareddy

<parameter>

<parameterName value="@message" />

<dbType value="String" />

<size value="4000" />

<layout type="log4net.Layout.PatternLayout">

<conversionPattern value="%message" />

</layout>

</parameter>

<parameter>

<parameterName value="@exception" />

<dbType value="String" />

<size value="2000" />

<layout type="log4net.Layout.ExceptionLayout" />

</parameter>

</appender>

o Colored Console Appender: The color mapping is completely configurable; these

appenders are only used for console based applications. Each <mapping /> element

must contain a severity level, and can also contain a <foreColor /> and/or <backColor />

element. Color selection is limited to the following choices: Blue, Green , Red, Yellow,

Purple, Cyan, White <appender name="ColoredConsoleAppender"

type="log4net.Appender.ColoredConsoleAppender">

<target value="Console.Error" />

<mapping>

<level value="FATAL" />

<foreColor value="Red" />

<backColor value="White" />

</mapping>

<mapping>

<level value="ERROR" />

<foreColor value="Red, HighIntensity" />

</mapping>

<mapping>

<level value="WARN" />

<foreColor value="Yellow" />

</mapping>

<mapping>

<level value="INFO" />

<foreColor value="Cyan" />

</mapping>

<mapping>

<level value="DEBUG" />

<foreColor value="Green" />

</mapping>

<layout type="log4net.Layout.SimpleLayout" />

</appender>

Page 7: Log 4 Net

Log4net

7 JayaKrishna Janapareddy

Appenders available in the Log4net distribution.

TYPE NAME DESCRIPTION

log4net.Appender.AdoNetAppender Appender that logs to a database.

log4net.Appender.AnsiColorTerminalAppender Appends logging events to the terminal using ANSI color escape sequences.

log4net.Appender.AspNetTraceAppender Appends log events to the ASP.NET Trace Context system.

log4net.Appender.BufferingForwardingAppender Buffers events and then forwards them to attached appenders.

log4net.Appender.ColoredConsoleAppender Appends logging events to the console.

log4net.Appender.ConsoleAppender Appends logging events to the console.

log4net.Appender.DebugAppender Appends log events to the Debug system.

log4net.Appender.EventLogAppender Writes events to the system event log.

log4net.Appender.ForwardingAppender This appender forwards logging events to attached appenders.

log4net.Appender.FileAppender Appends logging events to a file.

log4net.Appender.LocalSyslogAppender Logs events to a local syslog service.

log4net.Appender.MemoryAppender Stores logging events in an array.

log4net.Appender.NetSendAppender Logs entries by sending network messages using the NetMessageBufferSend native function.

log4net.Appender.OutputDebugStringAppender Appends log events to the OutputDebugString system.

log4net.Appender.RemoteSyslogAppender Logs events to a remote syslog daemon.

log4net.Appender.RemotingAppender Delivers logging events to a remote logging sink.

log4net.Appender.SmtpAppender Send an e-mail when a specific logging event occurs, typically on errors or fatal errors.

log4net.Appender.RollingFileAppender Appender that rolls log files based on size or date or both.

log4net.Appender.SmtpPickupDirAppender Send an email when a specific logging event occurs, typically on errors or fatal errors. Rather than sending via smtp it writes a file that another service, such as the IIS SMTP agent, can use to manage sending the messages.

log4net.Appender.TelnetAppender Appender that allows clients to connect via Telnet to receive log messages.

log4net.Appender.TraceAppender Appends log events to the Trace system.

log4net.Appender.UdpAppender Sends logging events as connectionless UDP datagrams to a remote host or multicast using the UdpClient class.

Using Multiple Appenders: With all the appenders available, we can use as many as we want.

Using multiple appenders is a simple task of specifying each appender you need under the root

logger.

Page 8: Log 4 Net

Log4net

8 JayaKrishna Janapareddy

<root>

<level value="ALL" />

<appender-ref ref="DebugAppender" />

<appender-ref ref="ColoredConsoleAppender" />

</root>

The root logger controls the general behavior of Log4net.

Layout: A layout is just a template for log message. Layouts are specified per appender, and you

can specify only one layout for appender. <appender name="ColoredConsoleAppender"

type="log4net.Appender.ColoredConsoleAppender">

<layout type="log4net.Layout.SimpleLayout" />

</appender>

Simple layout is the easiest layout to use and yields rather a Spartan log: DEBUG - this is a debug message

INFO - this is an info message

WARN - this is a warn message

ERROR - this is an error message

FATAL - this is a fatal message

Pattern layout allows us to specify a printf style template for log entries using a “conversion

pattern” and gives an opportunity to design each entry with some valuable instance data.

<appender name="ColoredConsoleAppender"

type="log4net.Appender.ColoredConsoleAppender">

<layout type="log4net.Layout.PatternLayout">

<conversionPattern value="%date [%thread] %-5level %logger -

%message%newline" />

</layout>

</appender>

Produces a log like this

2008-06-20 12:29:03,541 [2684] DEBUG Tutorial4.Program - this is a

debug message

2008-06-20 12:29:03,556 [2684] INFO Tutorial4.Program - this is an info

message

2008-06-20 12:29:03,556 [2684] WARN Tutorial4.Program - this is a warn

message

2008-06-20 12:29:03,556 [2684] ERROR Tutorial4.Program - this is an

error message

2008-06-20 12:29:03,556 [2684] FATAL Tutorial4.Program - this is a

fatal message

Page 9: Log 4 Net

Log4net

9 JayaKrishna Janapareddy

The conversion pattern string can include literal text and the following format expressions:

Expression Value

%appdomain the friendly name of the appdomain from which the log entry was made

%date the local datetime when the log entry was made

%exception a formatted form of the exception object in the log entry, if the entry contains an exception; otherwise, this format expression adds nothing to the log entry

%file the file name from which the log entry was made; note that using %file has a significant performance impact and I don't recommend using it

%identity the user name of the active user logging the entry; this one is less reliable than %username; note that using %identity has a significant performance impact and I don't recommend using it

%level the severity level of the log entry (DEBUG,INFO, etc)

%line the source code line number from which the log entry was made; slow

%location some rudimentary call stack information, including file name and line number at which the log entry was made; using

%logger the name of the logger making the entry; more on this in a bit

%method the name of the method in which the log entry was made; also slow

%message The log message itself (don't forget this part!)

%newline the value of Environment.NewLine

%timestamp the milliseconds between the start of the application and the time the log entry was made

%type the full typename of the object from which the log entry was made

%username the Windows identity of user making the log entry; slow

%utcdate the UTC datetime when the log entry was made

%% a percent sign (%)

This sample output is from a single log entry using a conversion pattern containing all of

the format expressions above:

%appdomain: Tutorial4_LayoutsAndPatterns.vshost.exe

%date: 2008-06-20 13:04:38,020

%exception:

%file:

D:\Project\Log4NetTutorial\Log4NetTutorial\Tutorial4_LayoutsAndPatterns

\Program.cs

%identity:

%level: INFO

%line: 14

%location:Tutorial4_LayoutsAndPatterns.Program.Main(D:\Project\Log4NetT

utorial\Log4NetTutorial\Tutorial4_LayoutsAndPatterns\Program.cs:14)

%logger: Tutorial4_LayoutsAndPatterns.Program

%method: Main

%message: this is an info message

%timestamp: 1015

%type: Tutorial4_LayoutsAndPatterns.Program

%username: MYDOMAIN\username

%utcdate: 2008-06-20 17:04:38,020

%%: %

Page 10: Log 4 Net

Log4net

10 JayaKrishna Janapareddy

Filters: Filters are applied to the individual appenders via the log4net configuration, and they

help the appender determine whether a log event should be processed by the appender. Filters

can be mixed and matched, but should be careful doing so. When a message fits inside the

criteria for a filter, it is logged and the processing of the filter is finished.

List of filters available in log4net configuration

TYPE NAME DESCRIPTION

log4net.Filter.LevelMatchFilter Filters log events that match a specific logging level; alternatively this can be configured to filter events that DO NOT match a specific logging level.

log4net.Filter.LevelRangeFilter Similar to the LevelMatchFilter, except that instead of filtering a single log level, this filters on an inclusive range of contiguous levels.

log4net.Filter.LoggerMatchFilter Filters log events based on the name of the logger object from which they are emitted.

log4net.Filter.StringMatchFilter Filters log events based on a string or regular expression match against the log message.

log4net.Filter.PropertyFilter Filters log events based on a value or regular expression match against a specific context property.

log4net.Filter.DenyAllFilter Effectively drops all logging events for the appender.

We can define our own filter by implementing the log4net.Filter.IFilter interface or deriving from

the log4net.Filter.FilterSkeleton class. We can apply multiple filters to an appender; they will be

evaluated as a chain in configuration order. Each filter in the chain can accept the message,

deny the message, or put to the next filter in the chain.

o Logger Match Filter: It filters against the name of the logger emitting the message. This

filter can be configured using the following properties

loggerToMatch: a string to match against the message’s logger name. The

match is made with the String.StartsWith method.

acceptOnMatch: a Boolean value indicating whether a matching logger name

results in accepting the message (true) or rejecting it (false). This defaults to

true, meaning that only matching logger names will be allowed into the

appender.

o Level Range Filter: A level range filter tells the system to only log entries that are inside

of the range specified. This range is inclusive, so in the below example, events with a

level of INFO, WARN, ERROR, or FATAL will be logged, but DEBUG events will be ignored. <filter type="log4net.Filter.LevelRangeFilter">

<levelMin value="INFO" />

<levelMax value="FATAL" />

</filter>

levelMin: the minimum log level to match - either DEBUG, INFO, WARN, ERROR,

or FATAL;

levelMax: the minimum log level to match - either DEBUG, INFO, WARN, ERROR,

or FATAL;

Page 11: Log 4 Net

Log4net

11 JayaKrishna Janapareddy

acceptOnMatch: a boolean value indicating whether to accept log levels

matching the levelToMatch property (true), or to punt filtering to the next filter

in the chain (false). Defaults to true. Note that any log level outside of the

[levelMin, levelMax] range is denied by this filter.

o Level Match Filter: The level match filter works like the level range filter, only it specifies

one and only one level to capture. However, it does not have the deny built into it so

you will need to specify the deny all filter after listing this filter. <filter type="log4net.Filter.LevelMatchFilter">

<levelToMatch value="ERROR"/>

</filter>

levelToMatch: the log level to match - either DEBUG, INFO, WARN, ERROR, or

FATAL;

acceptOnMatch: a Boolean value indicating whether to accept log levels

matching the levelToMatch property (true), or reject log levels matching the

levelToMatch property (false). Defaults to true.

o String Match Filter: The string match filter looks to find a specific string inside of the

information being logged. We can have multiple string match filters specified. They work

like OR statements in a query. <filter type="log4net.Filter.StringMatchFilter">

<stringToMatch value="test" />

</filter>

This filter can be configured as follows

regexToMatch: a regular expression to match against the log message. Note

this regex is created with the Compiled option enabled for performance;

stringToMatch: a static string to match against the log message. The match is

made using the String.IndexOf method to see if the static string exists in the log

message, which is a case-sensitive search.

acceptOnMatch: a Boolean value indicating whether to accept log messages

matching the string or regex (true), or to deny log messages matching the string

or regex (false). Defaults to true.

o Property Filter: It performs the same behavior as String Match Filter, except that the

match is made against the value of a context property.

key: the name of the property value to match;

regexToMatch: a regular expression to match against the specified property

value. Note this regex is created with the Compiled option enabled for

performance;

stringToMatch: a static string to match against the specified property value.

The match is made using the String.IndexOf method to see if the static string

exists in the property value, which is a case-sensitive search.

acceptOnMatch: a Boolean value indicating whether to accept messages with a

property value matching the string or regex (true), or to deny messages with a

property value matching the string or regex (false). Defaults to true.

Page 12: Log 4 Net

Log4net

12 JayaKrishna Janapareddy

o Deny All Filter: This filter simply denies all filtering. When this is used, it's always at the

end of a filter chain to block unwanted log messages from the appender. <filter type="log4net.Filter.DenyAllFilter" />

LOSSY LOGGING

Logging is a very useful tool, but it's not something we want to leave enabled in production if

you don't need it. Each log message take a few cycles away from our application, and the

persistence of messages does consume system resources. Of course we can configure log4net

to disable logging, either by setting the root logger level to OFF or removing all appenders from

the root logger. The problem is that by disabling logging altogether, we won't get any juicy

details if something goes awry in our application.

Lossy logging gives us a great compromise: under normal operation our application will not log

any messages; however, if our application logs an error, a small batch of messages leading up to

the error is placed into the log, giving you the error and a snapshot of system activity just before

it happened.

App.config: <?xml version="1.0" encoding="utf-8" ?>

<configuration>

<configSections>

<section name="log4net"

type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>

</configSections>

<log4net>

<appender name="ConsoleAppender"

type="log4net.Appender.ConsoleAppender">

<layout type="log4net.Layout.SimpleLayout" />

</appender>

<appender name="LossyConsoleAppender"

type="log4net.Appender.BufferingForwardingAppender">

<bufferSize value="20" />

<lossy value="true"/>

<evaluator type="log4net.Core.LevelEvaluator">

<threshold value="ERROR" />

</evaluator>

<appender-ref ref="ConsoleAppender" />

</appender>

<root>

<level value="DEBUG" />

<appender-ref ref="LossyConsoleAppender" />

</root>

</log4net>

</configuration>

Page 13: Log 4 Net

Log4net

13 JayaKrishna Janapareddy

The logging configuration defines two appenders, one very generic Console appender and a

BufferingForwardingAppender. As the name implies, the latter appender buffers log messages

and forwards them in batches to one or more other appenders. We can probably tell from the

configuration XML that I've set this appender up with a 20-message buffer. The lossy and

evaluator parameters work together to define when the log message buffer is forwarded to the

"base" appender.

Program: log4net.Config.XmlConfigurator.Configure();

static log4net.ILog Log = log4net.LogManager.GetLogger(

System.Reflection.MethodBase.GetCurrentMethod().DeclaringType

for( int i = 0; i < 100; ++i )

{

Log.DebugFormat( "this is debug msg #{0}", i );

}

Log.Error( "error: an error occurred!" );

Log.Warn( "warning: you've been warned" );

Output: DEBUG - this is debug msg #81

DEBUG - this is debug msg #82

DEBUG - this is debug msg #83

DEBUG - this is debug msg #84

DEBUG - this is debug msg #85

DEBUG - this is debug msg #86

DEBUG - this is debug msg #87

DEBUG - this is debug msg #88

DEBUG - this is debug msg #89

DEBUG - this is debug msg #90

DEBUG - this is debug msg #91

DEBUG - this is debug msg #92

DEBUG - this is debug msg #93

DEBUG - this is debug msg #94

DEBUG - this is debug msg #95

DEBUG - this is debug msg #96

DEBUG - this is debug msg #97

DEBUG - this is debug msg #98

DEBUG - this is debug msg #99

ERROR - error: an error occurred!

When the BufferingForwardingAppender's lossy property is enabled, the appender will buffer

log messages without forwarding them. If the buffer fills up, the oldest messages are dropped

from the buffer to make room for the new messages.

The evaluator property determines when the appender forwards the messages from the buffer

to its base appenders. There is only one evaluator defined in log4net - the LevelEvaluator. The

LevelEvaluator triggers the forward when a log message is received that meets or exceeds the

configured threshold. The example above is configured so that an ERROR message triggers the

appender to forward its buffer to the ConsoleAppender.

Page 14: Log 4 Net

Log4net

14 JayaKrishna Janapareddy

Lossy Appender Types: list of appenders in the log4net distribution that can operate "lossy:"

o log4net.Appender.AdoNetAppender

o log4net.Appender.RemotingAppender

o log4net.Appender.SmtpAppender

o log4net.Appender.SmtpPickupDirAppender

o log4net.Appender.BufferingForwardingAppender

REFERENCES:

http://www.beefycode.com/category/log4net.aspx

http://www.codeproject.com/Articles/140911/log4net-Tutorial