Log4Net: how to avoid Dummy entry created in Eventlog - log4net

I have created a sample program and every time I run this program, it is creating a dummy entry in the event log as below. How to avoid without creating a logger?
2014-02-24 18:04:53,557 [8] ERROR Log4NetSample.Program [(null)] - Error message
My Code:
using log4net;
using log4net.Config;
namespace Log4NetSample
{
class Program
{
static void Main(string[] args)
{
Program pg= new Program();
pg.Log4netCode();
}
private void Log4netCode()
{
XmlConfigurator.Configure();
ILog log = LogManager.GetLogger(typeof(Program));
log.Debug("Debug message");
log.Info("Info message");
log.Warn("Warning message");
log.Error("Error message");
log.Fatal("Fatal message");
}
}
}
Config file:
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="C:\Log\MyFirstLogger.log"/>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<maxSizeRollBackups value="2" />
<maximumFileSize value="2KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="WARN" />
</filter>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender">
<Eventid value="100"/>
<LogName value="Log4NetSample" />
<applicationName value="Log4NetSample" source="Api" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<levelMax value="ERROR" />
</filter>
</appender>
<root>
<level value="ERROR" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="EventLogAppender" />
</root>
</log4net>

You message is the actual to message from the line log.Error. You do not need to log or test you logger right after init the config.

Related

Configuring Log4Net for specific classes and overreaching error handling

I am using Log4Net within my project, and would like to configure it so that debug/info messages go to files specific to each class, and all error messages go to a central file.
Within my application, I have several "workers". I would like each worker to have its own log file to capture debug messages. If I get a debug message that isn't captured on a specific worker, I would like it to be logged to a central debug file. I would also like to have central error logging, where all errors from any of the workers are logged in the same file.
I am having difficulty figuring out the XML configuration to do this.
Here is the closest I have come:
<log4net>
<appender name="DebugLog" type="log4net.Appender.RollingFileAppender">
<file value="logs\debug.log" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="ddMMyyyy" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="FATAL" />
</filter>
</appender>
<appender name="ErrorLog" type="log4net.Appender.RollingFileAppender">
<file value="logs\error.log" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="ddMMyyyy" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline%stacktrace{1}%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<levelMax value="FATAL" />
</filter>
</appender>
<appender name="Worker1" type="log4net.Appender.RollingFileAppender">
<file value="logs\Worker1.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<datePattern value="ddMMyyyy" />
<maxSizeRollBackups value="100" />
<maximumFileSize value="100MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="INFO" />
</filter>
</appender>
<appender name="Worker2" type="log4net.Appender.RollingFileAppender">
<file value="logs\Worker2.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<datePattern value="ddMMyyyy" />
<maxSizeRollBackups value="100" />
<maximumFileSize value="100MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="INFO" />
</filter>
</appender>
<appender name="Worker3" type="log4net.Appender.RollingFileAppender">
<file value="logs\3.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<datePattern value="ddMMyyyy" />
<maxSizeRollBackups value="100" />
<maximumFileSize value="100MB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="INFO" />
</filter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="DebugLog" />
<appender-ref ref="ErrorLog" />
</root>
<logger name="Worker1">
<level value='DEBUG'/>
<appender-ref ref="Worker1" />
</logger>
<logger name="Worker2">
<level value='DEBUG'/>
<appender-ref ref="Worker2" />
</logger>
<logger name="Worker3">
<level value='DEBUG'/>
<appender-ref ref="Worker3" />
</logger>
</log4net>
The first issue I have is that all messages written to Worker1's class, are written to the Debug.log file, and the Worker1.log file. I don't want them written to Debug.log if they are already written to Worker1.log.
I can get around this by changing the section, by adding additivity = false. In this case, it writes to the Worker1.log, and not the Debug.log file.
However, doing this prevents errors from being written to Error.log
What happens is that if I set additivity = "false" and log an error, it gets written to Worker1.log, but does not get written to Error.log.
Is there any way to have the additivity apply to just the debug/info messages, so that I can have Debug messages in Worker1.log, Error messages in Error.log, and any debug messages that aren't specific to a logger in the debug.log file?
You are right about setting additivity="false" to isolate the debug messages to Worker1.log.
To get the error messages of Worker1 back into Error.log you also have to include the ErrorLog appender in the Worker1 logger declaration, as shown below.
<logger name="Worker1" additivity="false">
<level value='DEBUG'/>
<appender-ref ref="Worker1" />
<appender-ref ref="ErrorLog" />
</logger>
Via this setup you overrule the rules as defined in root to use a custom Worker1 Appender for debug messages and the same Error Appenderfor error messages.

log4Net filtering for multiple outputs confusion

Trying to understand the log4net filtering.
After reading the docs some aspects are still elusive to me.
For example I have this config file:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="..\Logs\CurrentLog" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000" />
<staticLogFileName value="true" />
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date [%thread] %-22.22c{1} - %m%n" />
</layout>
</appender>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<header value="Service Logging -- Start" />
<footer value="Service Logging -- End" />
<conversionPattern value="%date [%thread] %-5level %logger [%ndc]
<%property{auth}> - %message%newline" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<applicationName value="WindowsService1.exe" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
</layout>
</appender>
<!-- Set the default logging level and add the active appenders -->
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="RollingFileAppender" />
</root>
<!-- Specify the level for specific categories (“namespace.class”)-->
<logger name="WindowsService1.MyMonitor">
<level value="WARN" />
<appender-ref ref="EventLogAppender" />
</logger>
</log4net>
My expectations were:
The RollingFileAppender has a range of [INFO:FATAL] The Root has a
Level of DEBUG so it would let DEBUG and "greater" pass. Which
means all of RollingFileAppender's range would go through.
The LogFileAppender has no range specified so it would use Root's of DEBUG or greater.
And the EventLogAppender would only send event messages of WARN or greater to the Windows Event System - and - they would only
be messages from the class "WindowsService1.MyMonitor".
However it appears that all the messaging gets filtered to the WARN level!
Including my rolling log files and the log file "log-file.txt"
This seems like it should be simple - don't know why I'm so confused by it.
Hope someone can enlighten me.
Please feel free to use crayons and pictures because I think I need them.
Thanks.
UPDATE
In my Program.cs I have:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
And in each class where logging is done:
private static readonly ILog log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
UPDATE 2
At a different computer now. Had to recreate everything and used log4net debugging to assist.
But still can't get the desired output.
Basically want the WARN and above messages to go to one file and the Event logger. And those messages would be a subset of all the INFO and above messages.
The INFO and above messages - superset - would go into the rolling appender and overwrite themselves eventually. But the warnings and errors would always be maintained.
So here is a rework of all the files for a simple service. If I set WARN on the appender-ref ref=EventLogAppender then all the INFOs are suppressed.
Program.cs
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)]
// Ref: http://www.c-sharpcorner.com/UploadFile/naresh.avari/develop-and-install-a-windows-service-in-C-Sharp/
//
// use 'sc' to install/delete the service
// run 'sc' as administrator
// sc create "MySillyService" binpath= "C:\whatever\something.exe"
// sc delete "MySillyService"
namespace SimpleService1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
}
Service1.cs
namespace SimpleService1
{
public partial class Service1 : ServiceBase
{
private static readonly ILog log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private Timer timer1;
private int counter = 0;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer1 = new Timer();
timer1.Interval = 4000;
timer1.Elapsed += new ElapsedEventHandler(timer1_Tick);
timer1.Enabled = true;
log.Info("my service is started");
}
private void timer1_Tick(object sender, ElapsedEventArgs e)
{
counter++;
if (counter%2 == 0)
{
log.Info(String.Format("Counter({0:D}) is now even", counter));
}
else
{
log.Error(String.Format("Counter({0:D}) is now even", counter));
}
}
protected override void OnStop()
{
timer1.Enabled = false;
log.Info("my service was stopped");
}
}
}
App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\tmp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
</configuration>
Log4net.config
<?xml version="1.0" encoding="utf-8" ?>
<!--
Ref: http://mitch-wheat.blogspot.com/2007/04/log4net-net-logging-tool.html
I keep this config file in a separate directory and copy it with a
post-build event:
copy /Y $(SolutionDir)Logger\Log4Net.config $(TargetDir)Log4Net.config
-->
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="..\Logs\CurrentLog" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000" />
<staticLogFileName value="true" />
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date [%thread] %-22.22c{1} - %m%n" />
</layout>
</appender>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<header value="Service Logging -- Start - " />
<footer value="Service Logging -- End - " />
<conversionPattern value="%date [%thread] %-5level %logger [%ndc]
<%property{auth}> - %message%newline" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<applicationName value="Service1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
</layout>
</appender>
<!-- Set the default logging level and add the active appenders -->
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="RollingFileAppender" />
</root>
<!-- Specify the level for specific categories (�namespace.class�)-->
<logger name="SimpleService1.Service1">
<level value="WARN" />
<appender-ref ref="EventLogAppender" />
</logger>
</log4net>
Thanks for your help
Finally figured out the nuances to get this working as desired. Here's the config for anyone interested.
<?xml version="1.0" encoding="utf-8" ?>
<!--
I keep this config file in a separate directory and copy it with a
post-build event:
copy /Y $(SolutionDir)Logger\Log4Net.config $(TargetDir)Log4Net.config
-->
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="..\Logs\CurrentLog" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10000" />
<staticLogFileName value="true" />
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date [%thread] %-22.22c{1} - %m%n" />
</layout>
</appender>
<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
<file value="log-file.txt" />
<appendToFile value="true" />
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="WARN" />
<levelMax value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<header value="Service Logging -- Start - " />
<footer value="Service Logging -- End - " />
<conversionPattern value="%date [%thread] %-5level %logger [%ndc]
<%property{auth}> - %message%newline" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<!-- Put whatever name you want to display in the event log
for 'applicationName value=XX'
-->
<applicationName value="ServiceSkippy" />
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="WARN" />
<levelMax value="FATAL" />
</filter>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger
[%property{NDC}] - %message%newline" />
</layout>
</appender>
<!-- put namespace of service application in following name -->
<logger name="ServiceWithLog4Net">
<appender-ref ref="LogFileAppender" />
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="EventLogAppender" />
</logger>
</log4net>
-Skippy

Problems with Log4net multiple logger to multiple files

log4net version: 1.2.13.0
Runtime Version: v4.0.30319
I've got some Problems with using multiple Loggers and Appenders.
I have a root Logger with 3 Appenders which work well but when im configuring multiple other loggers log4net seems to only register the appenders from the last logger specified in the app.config.
If i put TaskSyncLogger as last logger entry TaskSyncAppender gets recognized
If i put CalendarSyncLogger as last logger entry CalendarSyncLogger gets recognized
only the 3 appenders from the root logger and the appender from the last logger entry is listed in hierarchy.GetAppenders()
Hierarchy hierarchy = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();
var appenders = hierarchy.GetAppenders();
my app.config
<appender name="MainFileAppender" type="log4net.Appender.FileAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger- %message%newline %exception" />
</layout>
<file value="Logs\logs.log" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
</appender>
<appender name="DebugAppender" type="log4net.Appender.DebugAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level - %message%newline %exception" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level - %message%newline %exception" />
</layout>
</appender>
<appender name="TaskSyncAppender" type="log4net.Appender.FileAppender">
<appendToFile value="true"/>
<file value="Logs\logsTask.log" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger- %message%newline %exception" />
</layout>
<!--
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
<filter type="log4net.Filter.DenyAllFilter" />
</filter>
-->
</appender>
<appender name="CalendarSyncAppender" type="log4net.Appender.FileAppender">
<appendToFile value="true"/>
<file value="Logs\logsCalendar.log" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger- %message%newline %exception" />
</layout>
<!--
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
<filter type="log4net.Filter.DenyAllFilter" />
</filter>
-->
</appender>
<root>
<level value="All" />
<appender-ref ref="MainFileAppender" />
<appender-ref ref="DebugAppender" />
<appender-ref ref="ConsoleAppender" />
</root>
<logger Name="CalendarSyncLogger" additivity="true">
<level value="All"/>
<appender-ref ref="CalendarSyncAppender"/>
</logger>
<logger Name="TaskSyncLogger" additivity="true">
<level value="All"/>
<appender-ref ref="TaskSyncAppender"/>
</logger>
further the TaskSyncAppender isn't writing anything the File gets created but it remains empty although the the MainFile Appender is writing the output.
im getting it like
public const string TaskSyncLogger = "TaskSyncLogger";
private static readonly ILog logTask = LogManager.GetLogger(LoggingStrings.TaskSyncLogger);
I can reproduce this, and while I cannot be confident in saying it is definitely a bug, it is certainly unexpected.
You can work around it by adding this last logger to your file:
<logger Name="WillNotBeUsed">
<level value="Off"/>
<appender-ref ref="CalendarSyncAppender"/>
<appender-ref ref="TaskSyncAppender"/>
</logger>
After that all five appenders are loaded.

log4net smtpappender subject based on log level

Is it possible to configure log4net to have two smtp appenders - one that sends emails only when log level is >= WARN and second that sends everything, but never two on the same time.
<appender name="SmtpAppenderWarn" type="log4net.Appender.SmtpAppender">
<to value="to#domain.com" />
<from value="from#domain.com" />
<subject value="Import completed with warnings / errors" />
<smtpHost value="localhost" />
<bufferSize value="512" />
<lossy value="true" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="WARN"/>
</evaluator>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%date [%thread] %-5level %logger [%property{NDC}] - %message%newline%newline%newline" />
</layout>
</appender>
<appender name="SmtpAppenderSuccess" type="log4net.Appender.SmtpAppender">
<to value="to#domain.com" />
<from value="from#domain.com" />
<subject value="Import completed successfully" />
<smtpHost value="localhost" />
<bufferSize value="512" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger: %message%newline" />
</layout>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="INFO" />
</filter>
</appender>
I my application I have:
Log.Info("Importer is starting...");
//my logic
//if warn Log.Warn("Warning...");
Log.Info("Import finished");
So I'm using INFO all the time. Now when I encounter WARN both messages are being sent. I wish of course that the one with success info was not sent.
I have solved the problem by overriding log4net SendBuffer method:
namespace MyProject
{
public class SmtpAppenderInfoOnly : SmtpAppender
{
protected override void SendBuffer(log4net.Core.LoggingEvent[] events)
{
foreach (var loggingEvent in events)
{
if (loggingEvent.Level != Level.Info)
return;
}
base.SendBuffer(events);
}
}
}
And then in config file:
<appender name="SmtpAppenderSuccess" type="MyProject.SmtpAppenderInfoOnly,MyDll">
That way the SendMail method will not be executed when SendBuffer is canceled.
Your appenders can have min/max values like so:
<levelMin value="INFO" />
<levelMax value="INFO" />
<levelMin value="WARN" />
<levelMax value="WARN" />
So you can use different appenders for different ranges. I believe this should work for you.

log4net ForwardingAppender threshold

I need to configure logger to write messages to several appenders with different Log Levels.
For ex. I want RefreshDataService to log detailed info to TransportFileAppender and Warnings and Errors to RollingFileAppender.
Also, I'm using buffering to improve logging performance.
I setup FilteredFileLog appender to forward Warnings to FileLog->RollingFileAppender.
But for RefreshDataService logger, all log messages including debug and Info getting logged to FileLog.
Can you help me to configure the RefreshDataService logger to log only Warn+ messages to FileLog? Thanks.
Below is excerpt from my log4net config.
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="${TEMP}\logs\client\${ENV}\client.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="4096KB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level [%property{ENV}] [%property{UID}] %logger - %message%newline" />
</layout>
</appender>
<appender name="TransportAppender" type="log4net.Appender.RollingFileAppender">
<file value="${TEMP}\logs\client\${ENV}\client.comm.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="4096KB" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="DetailedTransportLog" type="log4net.Appender.BufferingForwardingAppender">
<threshold value="DEBUG" />
<bufferSize value="200" />
<appender-ref ref="TransportAppender" />
</appender>
<appender name="FileLog" type="log4net.Appender.BufferingForwardingAppender">
<bufferSize value="20" />
<lossy value="false" />
<appender-ref ref="RollingFileAppender" />
</appender>
<appender name="FilteredFileLog" type="log4net.Appender.ForwardingAppender">
<threshold value="WARN" />
<appender-ref ref="FileLog" />
</appender>
<logger name="RefreshDataService" >
<level value="DEBUG" />
<appender-ref ref="FilteredFileLog" />
<appender-ref ref="DetailedTransportLog" />
</logger>
You can use a level range filter on the appender:
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="WARN" />
<levelMax value="FATAL" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
My understanding is that the Threshold property is used tell the appender to flush the buffer when messages of a certain level are logged. This way you can make for instance sure that errors are written immediately to the database.

Resources