Logging with log4net
2023-01-11 C# log4net logging DebugAppender LevelRangeFilterFor user support I usually found very useful to setup some kind of logging for each program I work on. A very flexible logging solution is log4net. It provides nice separation of actual logging in the application and configurable output. For long-running applications it also allows to change the configuration and add more details in the runtime.
Here is how to setup the logging in C# project. The App.config
refers to log4net.config
via appSettings section
<appSettings>
<add key="log4net.Config" value="log4net.config" />
<add key="log4net.Config.Watch" value="True" />
</appSettings>
The log4net.config
sets up the minimal level of logging and appenders. I usually use the logging to inform about application progress (prints to standard output) and to produce rolled log
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<log4net>
<root>
<level value="Info" />
<appender-ref ref="file" />
<appender-ref ref="console" />
<appender-ref ref="debug" />
</root>
<appender name="debug" type="log4net.Appender.DebugAppender">
<category value="" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%file(%line): %message%newline" />
</layout>
</appender>
<appender name="console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message%newline" />
</layout>
</appender>
<appender name="file" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
<appendToFile value="false" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %logger - %message%newline" />
</layout>
</appender>
</log4net>
</configuration>
A nice bonus is DebugAppender which prints into Visual Studio output console, including the place in source code.
Each appender can also filter entries, e.g. using LevelRangeFilter in the appender section.
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="FATAL" />
</filter>
In the application then just initialize a logger and use it
public class CodeManager
{
private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public void GenerateOutputs()
{
log.Info("Generating outputs");
...
try
{
}
catch(Exception e)
{
log.Error($"Failed processing {file}: {e}");
}
}
}