Elton Stoneman

  Home  |   Contact  |   Syndication    |   Login
  83 Posts | 0 Stories | 118 Comments | 0 Trackbacks

News

Archives

Post Categories

[Source: http://geekswithblogs.net/EltonStoneman]

The venerable log4net library enables cheap instrumentation with configured logging levels, so logs are only written if the log call is on or above the active level. However, the evaluation of the log message always takes place, so there is some performance hit even if the log is not actually written. You can get over this by using delegates for the log message, which are only evaluated based on the active log level:

public static void Log(LogLevel level, Func<string> fMessage)

{

if (IsLogLevelEnabled(level))

{

LogInternal(level, fMessage.Invoke());

}

}

Making the delegate call with a lambda expression makes the code easy to read, as well as giving a performance saving:

Logger.Log(LogLevel.Debug,

() => string.Format("Time: {0}, Config setting: {1}",

DateTime.Now.TimeOfDay,

ConfigurationManager.AppSettings["configValue"]));

For simple log messages, the saving may be minimal, but if the log involves walking the current stack to retrieve parameter values, it may be worth having. The sample above writes the current time and a configuration value to the log, if set to Debug. With the log level set to Warn, the log isn't written. Executing the call 1,000,000 times at Warn level consistently takes over 3.7 seconds if the logger call is made directly, and less than 0.08 seconds if the Lambda delegate is used:

With a Warn call, the log is active and the direct and Lambda variants run 5,000 calls in 8.6 seconds, writing to a rolling log file appender:

I've added the logger and test code to the MSDN Code Gallery sample: Lambda log4net Sample, if you're interested in checking it out.

posted on Wednesday, April 15, 2009 11:08 PM

Feedback

# re: Making Logging Cheaper with Lambda Expressions 4/17/2009 11:09 AM andyclap
Nice, however one of the advantages of log4net over some other logging libraries is the loglevel can be simply queried before writing. It's already good practice to use code like
if (log.IsWarnEnabled) log.Warn("Warning!");

An expression based version is certainly the way to go for loging interfaces that don't let you know the loglevel (e.g. Enterprise Blechs).


Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: