Can I send one log message to a particular appender? - c#

I've got a logger which is using a file appender and a console appender. I've got one line in my code that I only want to go to the console appeander. Is there a way to do that without making a while new logger?
Alternatively, I could just make another logger that only used the console, but I can't seem to even get that done. All examples I can find use class or method names. I am trying to use a name I provided in the app.config.
Here is my appconfig:
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<conversionPattern value="%level [%thread] %date - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="All" />
</filter>
</appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="D:\Something\Log\IntegrationTests\IntegrationTests.log" />
<appendToFile value="false" />
<rollingStyle value="Size" />
<maximumFileSize value="250MB" />
<maxSizeRollBackups value="20" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level [%thread] %date - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="All" />
</filter>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>
<logger name="consoleOnly">
<level value="ALL" />
<appender-ref ref="Console" />
</logger>
</log4net>
Here is a line where I try to get "consoleOnly" Logger.
ILog log = LogManager.GetLogger("consoleOnly");
log.Debug("Poop");
Is that how I do it?

ILog log = LogManager.GetLogger("consoleOnly");
log.Debug("Poop");
This should work fine. but I think you need to set additivity to false, otherwise it would also log using the root logger.
eg.
<logger name="consoleOnly" additivity="false">
<level value="ALL" />
<appender-ref ref="Console" />
</logger>

Related

Log4net - Logging to wrong appender

I'm trying to have 2 log files, with my application logging to either by specifying a logger name in code.
The problem is it never logs to the file I'm trying to target, instead it always logs to the last declared appender in the config (LogB in this case).
I have my config set up as follows:
<log4net>
<logger name="LogA">
<appender-ref ref="LogA"/>
<level value="DEBUG"/>
</logger>
<logger name="LogB">
<appender-ref ref="LogB"/>
<level value="DEBUG"/>
</logger>
<appender name="LogA" type="log4net.Appender.FileAppender">
<file value="E:\Logs\LogA.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="LogB" type="log4net.Appender.FileAppender">
<file value="E:\Logs\LogB.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="LogA" />
</root>
<root>
<level value="DEBUG" />
<appender-ref ref="LogB" />
</root>
</log4net>
Then in my code when I create a logger:
private static readonly ILog logA = LogManager.GetLogger("LogA");
log.Debug("This should log to LogA");
And in some other class:
private static readonly ILog logB = LogManager.GetLogger("LogB");
log.Debug("This should log to LogB");
But nothing is ever logged to the LogA file, it's always output to the LogB file (or whatever happens to appear last in the config).
What is it I'm missing?
For some reason it didn't appear to like the multiple root nodes. When I used this setup instead (keeping the appender nodes), it worked:
<root>
<level value="ALL" />
<appender-ref ref="SomeRootAppender" />
</root>
<logger additivity="false" name="LogA">
<level value="DEBUG"/>
<appender-ref ref="LogA" />
</logger>
<logger additivity="false" name="LogB">
<level value="DEBUG"/>
<appender-ref ref="LogB" />
</logger>

log4net filtering by <logger> not working

I would like to filter out certain log entries. In my config file I've tried adding the following to my appender with no luck:
<logger name="NHibernate">
<level value="ERROR" />
</logger>
<logger name="NHibernate.SQL">
<level value="ERROR" />
</logger>
<logger name="Castle">
<level value="ERROR" />
</logger>
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="/*repeat for all the above*/" />
<acceptOnMatch value="false" />
</filter>
Here's the whole file, where the two <logger/> sections are is where I tried putting the rest of my filter attempts as well. Only concerned about the RollingFileAppender right now.
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="C:\log\auto.log" />
<appendToFile value="true" />
<maximumFileSize value="1000KB" />
<maxSizeRollBackups value="10" />
<logger name="NHibernate" additivity="false">
<level value="OFF" />
</logger>
<logger name="NHibernate.SQL" additivity="false">
<level value="OFF" />
</logger>
<layout type="log4net.Layout.PatternLayout">
<footer value ="
"/>
<conversionPattern value="%date %level - %message%newline%exception" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFile" />
</root>
</log4net>
You need to move the logger configuration outside the appenders: loggers reference which appenders to use, but are not part of the appender configuration. Also you should remove the additivity=false as that's redundant.
Womp, I don't know how log4net works.
All those <logger/> tags go right after the opening <log4net> tag like so
<log4net>
<logger name="NHibernate" >
<level value="ERROR" />
</logger>
<logger name="NHibernate.SQL">
<level value="ERROR" />
</logger>
...

How to configure multiple logging configurations using log4net?

I am using the following app.config settings for multiple log files. The following are my app.config settings. But when I use "LogFileAppender" settings to write log to a file, it also writing the logs to the Console
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<File value="C:\File1.log" />
<AppendToFile value="true" />
<rollongStyle value="Composite" />
<maximumFileSize value="200MB" />
<layout type="log4net.Layout.PatternLayout">
<ConversionPattern value="%date %messge%newline"/>
</layout>
</appender>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<File value="C:\File2.log" />
<AppendToFile value="true" />
<rollongStyle value="Date" />
<maximumFileSize value="100MB" />
<layout type="log4net.Layout.PatternLayout">
<ConversionPattern value="%date %messge%newline"/>
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="INFO" />
</filter>
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
<levelMin value="FATAL" />
</filter>
</appender>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value ="ERROR"/>
<foreColor value ="Red"/>
</mapping>
<mapping>
<level value ="WARN"/>
<foreColor value ="Yellow"/>
</mapping>
<layout type="log4net.Layout.PatternLayout">
<ConversionPattern value="%date %messge%newline"/>
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="RollingFile" />
<appender-ref ref="ColoredConsoleAppender" />
</root>
</log4net>
In the C# code, I am using the below method calls.
private static readonly log4net.ILog ilogger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
log4net.Config.XmlConfigurator.Configure();
Question:
How can I restrict the Console logging while using the LogFileAppender using the above app.config file?
Add a ForwardingAppender in your configuration between the root logger and the ColoredConsoleAppender, so that you get this configuration
root -> LogFileAppender
root -> RollingFile
root -> ForwardingAppender -> ColoredConsoleAppender
Then in your ForwardingAppender add a filter that will only let pass events that do not originate from the application you don't want; a LoggerMatchFilter would be a good idea since you can exclude loggers originating from the namespace of the desired application.
I found the solution by modifying the app.config as following.
<logger name = "FileLogger" additivity="false">
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</logger>
<root>
<level value="ALL"/>
<appender-ref ref="RollingFile"/>
<appender-ref ref="RollingFileAppender" />
<appender-ref ref="ColoredConsoleAppender" />
</root>
In the C# code, call the LogFileAppender explicitly as below
private static readonly log4net.ILog ilogger = log4net.LogManager.GetLogger("FileLogger");

Block logging for assemblies having separate loggers in log4net

I have two log files written from my application, which have multiple assemblies in the following manner:
Assembly1 log -> MainLog.log
Assembly2 log -> MainLog.log
Assembly3 log -> MainLog.log
Assembly4 log -> MainLog.log
Assembly5 log -> SubLog.log
Assembly6 log -> SubLog.log
The log files get written correctly, but the problem here is, the SubLog entries get written into the MainLog file as well. I don't want this kind of logging duplication to happen. This is my log4net configuration.
<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs//MainLog.txt" />
<appendToFile value="true" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100KB" />
<rollingStyle value="Size" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%M %date [%thread] %-5level %logger [%ndc] - %message %C, %F, %l, %L %M %newline" />
</layout>
</appender>
<appender name="NewForEveryRun" type="log4net.Appender.FileAppender">
<file type="log4net.Util.PatternString" value="Logs//SubLog-%processid.txt"/>
<appendToFile value="true" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<logger name="Assembly5">
<level value="DEBUG"/>
<appender-ref ref="NewForEveryRun"/>
</logger>
<logger name="Assembly6">
<level value="DEBUG"/>
<appender-ref ref="NewForEveryRun"/>
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender" />
</root>
For Assembly5 and Assembly6, I've specified the appender NewForEveryRun. In addition to this, I've kept the root, so that the rest of the assemblies are logged according to configuration specified in the RollingLogFileAppender appender. I guess, the root element is logging all the assemblies by default, even if I mention different logger for other assemblies. Is there any way to block the logging of Assembly5 and Assembly6 from root?
Got it! The loggers should look like this:
<logger name="Assembly5" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="NewForEveryRun"/>
</logger>
<logger name="Assembly6" additivity="false">
<level value="DEBUG"/>
<appender-ref ref="NewForEveryRun"/>
</logger>
Setting additivity as false is the solution. No more duplicate logging :)

log4net not logging debug statements

I am using log4net for the first time and have followed the documentation using supplied configuration samples, however debug statements do not log.
Info, Error, Warn and Fatal levels all log correctly. Can anyone tell me what I am missing?
app.config:
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
<log4net>
<appender name="Console" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="INFO" />
<foreColor value="Green"/>
</mapping>
<mapping>
<level value="DEBUG" />
<foreColor value="Cyan,HighIntensity"/>
</mapping>
<mapping>
<level value="WARN" />
<foreColor value="Purple,HighIntensity"/>
</mapping>
<mapping>
<level value="ERROR" />
<foreColor value="Red,HighIntensity"/>
</mapping>
<mapping>
<level value="FATAL" />
<foreColor value="Yellow,HighIntensity"/>
</mapping>
<layout type="log4net.Layout.PatternLayout">
<!-- Pattern to output the caller's file name and line number -->
<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
</layout>
</appender>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="example.log" />
<appendToFile value="true" />
<maximumFileSize value="100KB" />
<maxSizeRollBackups value="2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level %thread %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>
</log4net>
Some people have mentioned checking AssemblyInfo for [assembly: log4net.Config.XmlConfigurator()], however there is no difference with or without this line.
Logger is declared like:
private static readonly ILog log = LogManager.GetLogger( typeof( CWD_Netsuite ) );
and is accessed like:
XmlConfigurator.Configure();
log.Debug("Debugging"); //does not get logged
log.Info( "Entering Application" ); //logged to console and log file
log.Debug( "Debug Statement" ); //does not get logged
log.Error( "Error statement" ); //logged to console and log file
log.Warn( "Warning statement" ); //logged to console and log file
log.Fatal( "Fatal Statement" ); //logged to console and log file
You have a filter set to INFO level in your root category (thus filtering out any messages of DEBUG level):
<root>
<level value="INFO" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>
Change it to
<level value="DEBUG" />
The log4net levels are defined in the following order:
ALL,
DEBUG,
INFO,
WARN,
ERROR,
FATAL,
OFF
Based on your current settings you are writing everything with INFO and below.
Set your root node to the following:
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>
Change the level value to "DEBUG" in your node...
<root>
<level value="DEBUG" />
<appender-ref ref="Console" />
<appender-ref ref="RollingFile" />
</root>

Categories