One of the often-cited arguments against logging is its computational cost. This is a legitimate concern as even moderately sized applications can generate thousands of log requests. Much effort was spent measuring and tweaking logging performance. Log4net claims to be fast and flexible: speed first, flexibility second.
The user should be aware of the following performance issues.
However, The method invocation involves the "hidden" cost of parameter construction.
For example, for some logger log, writing,
log.Debug("Entry number: " + i + " is " + entry[i].ToString());
incurs the cost of constructing the message parameter, i.e. converting both integer i and entry[i] to strings, and concatenating intermediate strings, regardless of whether the message will be logged or not. This cost of parameter construction can be quite high and it depends on the number and type of the parameters involved.
To avoid the parameter construction cost write:
if(log.IsDebugEnabled) { log.Debug("Entry number: " + i + " is " + entry[i].ToString()); }
This will not incur the cost of parameter construction if debugging is disabled. On the other hand, if the logger is debug-enabled, it will incur twice the cost of evaluating whether the logger is enabled or not: once in IsDebugEnabled and once in Debug. This is an insignificant overhead because evaluating a logger takes about 1% of the time it takes to actually log.
Certain users resort to pre-processing or compile-time techniques to compile out all log statements. This leads to perfect performance efficiency with respect to logging. However, since the resulting application binary does not contain any log statements, logging cannot be turned on for that binary. In many people's opinion this is a disproportionate price to pay in exchange for a small performance gain.
There has been a serious effort to make this hierarchy walk to be as fast as possible. For example, child loggers link only to their existing ancestors. In the BasicConfigurator example shown earlier, the logger named Com.Foo.Bar is linked directly to the root logger, thereby circumventing the nonexistent Com or Com.Foo loggers. This significantly improves the speed of the walk, especially in "sparse" hierarchies.
The typical cost of walking the hierarchy is typically 3 times slower than when logging is turned off entirely.
Although log4net has many features, its first design goal was speed. Some log4net components have been rewritten many times to improve performance. Nevertheless, contributors frequently come up with new optimizations. You should be pleased to know that when configured with the SimpleLayout performance tests have shown log4net to log within an order of magnitude of System.Console.WriteLine.
The following is the series of steps and checks that a messages goes through while being logged. For the purposes of this example we will document an INFO level message being logged on logger ConsoleApp.LoggingExample. This logger is configured to use the log4net.Appender.ConsoleAppender. The repository used in this example is a log4net.Repository.Hierarchy object.
For Each Appender that the LoggingEvent is delivered to the following actions take place:
The following actions take place in the ConsoleAppender.Append method: