Two different FileAppender writing same logs message in two log files - c#

I am getting a problem, when I configured two appenders and try to write a log message to one of the apender this also write the same message to another appenders file. Below is the configuration section,
<log4net>
<root>
<level value="INFO" />
<appender-ref ref="ErrorLog" />
<appender-ref ref="PayWinSrvLog" />
</root>
<appender name="ErrorLog" type="log4net.Appender.FileAppender">
<param name="File" value="E:\Webhome\FimFolders\BankWinserviceService\Error_Log.txt" />
<param name="AppendToFile" value="true" />
<maxSizeRollBackups value="0" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<maximumFileSize value="2MB" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
</layout>
</appender>
<appender name="PayWinSrvLog" type="log4net.Appender.FileAppender">
<param name="File" value="E:\Webhome\FimFolders\BankWinserviceService\PayWinSrv_Log.txt" />
<param name="AppendToFile" value="true" />
<maxSizeRollBackups value="0" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<maximumFileSize value="2MB" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d [%t] %-5p %c %m%n" />
</layout>
</appender>
and this is the only code I am using in Start method of my windows service project.
protected override void Start()
{
ErrorLog = LogManager.GetLogger("ErrorLog");
PayWinSrvLog = LogManager.GetLogger("PayWinSrvLog");
XmlConfigurator.Configure();
ErrorLog.Error("Error Message."); // this also get printed in PayWinSrv_Log.txt
}
I also include the line
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
excuse me for my English.

You're getting confused with Appenders and Loggers. A log itself can have multiple appenders (e.g. you could have an SmtpAppender and a FileAppender for an error log, but you may want a separate FileAppender for normal messages). Since you only configure the root logger, using <root>..., then that is the only log that is ever returned using LogManager.GetLogger, which in your configuration has both FileAppenders.
To configure multiple, separate logs, use <logger tags, and then specify the appenders for each log:
<logger name="ErrorLog">
<level value="INFO" />
<appender-ref ref="ErrorLog" />
</logger>
<logger name="PayWinSrvLog">
<level value="INFO" />
<appender-ref ref="PayWinSrvLog" />
</logger>

Related

Can I send one log message to a particular appender?

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>

C# Log4Net Writing To Both Appenders

I am using C# to write an in house application and we've been trying to figure out a resolution to this issue for a couple of days now. We're using Log4Net v1.2.15.0 compiling against .Net v4.5.2. I have two rolling file appenders, EventsLogger and SitrepLogger which are both set to write to the network. I have confirmed that this does work as intended however when I call one appender (doesn't matter which) to write out, it writes to both EventsLogger and SitrepLogger files. Here is the relevant data from my app.config
<log4net>
<appender name="EventsLogger" type="log4net.Appender.RollingFileAppender">
<file name="File" value="\\TS-WXLF41\Project\Ambushed\${USERNAME}\EventsLog" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="1MB" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<param name="StaticLogFileName" value="false"/>
<param name="RollingStyle" value="Date"/>
<param name="DatePattern" value="_MM-dd-yy.\tx\t" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%newline%date{HH:mm:ss tt} %message" />
</layout>
</appender>
<appender name="SitrepLogger" type="log4net.Appender.RollingFileAppender">
<file name="File" value="\\TS-WXLF41\Project\Ambushed\${USERNAME}\logs\sitrep" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="5" />
<maximumFileSize value="1MB" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<param name="StaticLogFileName" value="false"/>
<param name="RollingStyle" value="Date"/>
<param name="DatePattern" value="_MM-dd-yy.\tx\t"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%newline%newline%date{HH:mm:ss tt} %message" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="EventsLogger" />
<appender-ref ref="SitrepLogger" />
</root>
</log4net>
In my Program's entry point constructor I call log4net.Config.XmlConfigurator.Configure(); which I am pretty sure is working as intended. I do not call Configure anywhere else in the code except from there. In the members are of my entry point class I call private static readonly log4net.ILog logger = log4net.LogManager.GetLogger("SitrepLogger"); to fetch the logger that I need for my Program (entry point) class. In my other classes I use the EventsLogger so I call private static readonly log4net.ILog eventslogger = log4net.LogManager.GetLogger("EventsLogger"); in the members are of those classes. I do not call GetLogger more than once per class and I am sure I invoking the correct appender by calling eventslogger.Info()
This used to work fine (using multiple appenders to write to different files) for us but we've made many many changes since then, which we have tried reverting to with no success. No errors, no warnings and no messages on compilation. Thank you for everything in advance! :)
You are confusing appenders and loggers. Your application is creating loggers "SitrepLogger" and "EventsLogger". These both inherit the configuration of the root logger, and write to appenders with the same names "SitrepLogger" and "EventsLogger".
Try the following configuration, which I think will give you what you want:
<log4net>
<appender name="EventsAppender" ... >
...
</appender>
<appender name="SitrepAppender" ... >
...
</appender>
<root>
<level value="ALL" />
</root>
<logger name="EventsLogger" additivity="False">
<appender-ref ref="EventsAppender" />
</logger>
<logger name="SitrepLogger" additivity="False">
<appender-ref ref="SitrepAppender" />
</logger>
</log4net>

Use current class name as name for log folder in log4net

I've created a scheduler project (console application with quartz.net) that contains several classes (jobs) that will be executed recurrently. I'm using log4Net to create the log files and right now every job is appending it's messages to the same file called scheduler/Scheduler.Info.txt. I would like to have a differente folder for each scheduler job.
what I have now is every job appending on
scheduler/scheduler/scheduler.Info.txt
what I want is:
scheduler/SomeJob1/SomeJobJob1.Info.txt
scheduler/SomeJob2/SomeJobJob2.Info.txt
scheduler/SomeJob3/SomeJobJob3.Info.txt
So, the pattern is
scheduler/{CLASS NAME}/{CLASS NAME}.Info.txt
My current configuration for log4net:
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="SchedulerLogFileInfoAppender" />
</root>
<appender name="SchedulerLogFileInfoAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="c:\Scheduler\Scheduler.Info.log" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{dd/MM/yy HH:mm:ss} - %p - %logger - %m%n" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMax value="INFO" />
</filter>
</appender>
</log4net>
And this is one of the jobs logging a message:
public class SomeJob1: IJob
{
private static readonly ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
...
private void DoStuff()
{
logger.Info("THIS IS A MESSAGE");
...
}
}

Root log all level

My root logger catches all levels of log except off. My level is set to INFO.
I searched if the level was changed somewhere, but I found nothing.
When I put the logger IBatisNet.DataMapper.Commands.DefaultPreparedCommand to DEBUG, the log is created in a text file by SpecificAppender. But, the log also appears in the console even if the root is set to INFO.
This is my code:
<?xml version="1.0" encoding="utf-8" ?>
<!-- This section contains the log4net configuration settings -->
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<!-- Define some output appenders -->
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="d:/logs/vol/vol.log" />
<param name="AppendToFile" value="true" />
<param name="MaxSizeRollBackups" value="3" />
<param name="MaximumFileSize" value="500KB" />
<param name="RollingStyle" value="Size" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,fff} [%t] %-5p %c{1} - %m%n" />
</layout>
</appender>
<appender name="IBatisAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="d:/logs/vol/IBatis.log" />
<param name="AppendToFile" value="true" />
<param name="MaxSizeRollBackups" value="3" />
<param name="MaximumFileSize" value="1000KB" />
<param name="RollingStyle" value="Size" />
<param name="StaticLogFileName" value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,fff} [%t] %-5p %c{1} - %m%n" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,fff} [%t] %-5p %c{1} - %m%n" />
</layout>
</appender>
<appender name="IBatisBufferingAppender" type="log4net.Appender.BufferingForwardingAppender" >
<bufferSize value="60"/>
<appender-ref ref="IBatisAppender" />
</appender>
<appender name="LogBufferingAppender" type="log4net.Appender.BufferingForwardingAppender" >
<bufferSize value="60"/>
<appender-ref ref="RollingLogFileAppender" />
</appender>
<appender name="SpecificAppender" type="log4net.Appender.RollingFileAppender">
<file value="d:/logs/vol/" />
<appendToFile value="true"/>
<datePattern value="Volu\me\trieSpeci\fic_yyyy-MM-dd.lo\g"/>
<rollingStyle value="Date"/>
<maxSizeRollBackups value="30"/>
<appendToFile value="true"/>
<staticLogFileName value="false"/>
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:SS,fff} [%t] %-5p %c{1} - %m%n" />
</layout>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="No -->"/>
<acceptOnMatch value ="true" />
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="Statement Id: [vol.Delete"/>
<acceptOnMatch value ="false" />
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="] Types: ["/>
<acceptOnMatch value ="false" />
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="Statement Id: [vol."/>
<acceptOnMatch value ="true" />
</filter>
<filter type="log4net.Filter.DenyAllFilter"/>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="LogBufferingAppender" />
</root>
<logger name="PROGvolBatch.Services.CIService">
<level value="INFO" />
<appender-ref ref="SpecificAppender"/>
</logger>
<logger name="IBatisNet.DataMapper.Commands.DefaultPreparedCommand">
<level value="DEBUG" />
<appender-ref ref="SpecificAppender"/>
</logger>
<logger name="IBatisNet.DataMapper.Configuration.Cache.CacheModel">
<level value="OFF" />
<appender-ref ref="IBatisBufferingAppender" />
</logger>
<logger name="IBatisNet.DataMapper.LazyLoadList">
<level value="OFF" />
<appender-ref ref="IBatisBufferingAppender" />
</logger>
<logger name="IBatisNet.DataMapper.SqlMapSession">
<level value="OFF" />
<appender-ref ref="IBatisBufferingAppender" />
</logger>
<logger name="IBatisNet.Common.Transaction.TransactionScope">
<level value="OFF" />
<appender-ref ref="IBatisBufferingAppender" />
</logger>
<logger name="IBatisNet.DataAccess.DaoSession">
<level value="OFF" />
<appender-ref ref="IBatisBufferingAppender" />
</logger>
<logger name="IBatisNet.DataAccess.Configuration.DaoProxy">
<level value="OFF" />
<appender-ref ref="IBatisBufferingAppender" />
</logger>
<logger name="IBatisNet.DataMapper.Configuration.Statements.PreparedStatementFactory">
<level value="OFF" />
<appender-ref ref="IBatisBufferingAppender" />
</logger>
<logger name="IBatisNet.DataMapper.Commands.IPreparedCommand">
<level value="OFF" />
<appender-ref ref="IBatisBufferingAppender" />
</logger>
</log4net>
I tried changing the level of the root to something else, but I always got the same result.
This appears to be the way log4net works. When your config file is processed it behaves as if it has been configured like:
<logger name="IBatisNet.DataMapper.Commands.DefaultPreparedCommand" additivity="false">
<level value="DEBUG" />
<appender-ref ref="SpecificAppender"/>
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="LogBufferingAppender" />
</logger>
Fortunately there is a workaround and that is to set a level filter on your appenders, e.g. for the ConsoleAppender:
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,fff} [%t] %-5p %c{1} - %m%n" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<acceptOnMatch value="true" />
</filter>
</appender>
It might also be better to rename the appender to something more descriptive like InfoConsoleAppender. Also, if you want to be able to log some loggers to console at debug level, then you may need another un-filtered ConsoleAppender.

I would like to create two log files - one with "DEBUG" another with "INFO" logs only

I have here this log4net config:
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="D:\logfolder\logfile.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="20MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
</appender>
</log4net>
This is working well, but I would like to create another logfile with only "INFO" input. Is it possible to log in two different files, without changing anything in my C# code, just changing the config file?
Or lets just make the question simple: What do I have to add exactly to my config file?
And also, I have another issue: if I choose "INFO" instead of "DEBUG", I get INFO + ERROR logs. can I change this somehow, not to get ERROR logs, just INFO? Thank you.
You can configure second appender with filter specified, and add it to your root logger.
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="AnotherLogFileAppender" />
</root>
<appender name="LogFileAppender"
type="log4net.Appender.RollingFileAppender">
...
</appender>
<appender name="AnotherLogFileAppender"
type="log4net.Appender.RollingFileAppender">
<param name="File" value="D:\logfolder\anotherlogfile.txt" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="20MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern"
value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="INFO"/>
<param name="LevelMax" value="INFO"/>
</filter>
</appender>
</log4net>
Also consider to use new style of log4net configuration, rather than old one with param tags:
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
<appender-ref ref="AnotherLogFileAppender" />
</root>
<appender name="LogFileAppender"
type="log4net.Appender.RollingFileAppender">
<file value="D:\logfolder\logfile.txt"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="20MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n"/>
</layout>
</appender>
<appender name="AnotherLogFileAppender"
type="log4net.Appender.RollingFileAppender">
<file value="D:\logfolder\anotherlogfile.txt"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="10"/>
<maximumFileSize value="20MB"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n"/>
</layout>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="INFO"/>
</filter>
</appender>
</log4net>

Categories