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
Appender
for error
messages.