I implemented Console application that can run as Windows service (very similar to .NET console application as Windows service).
.NET framework 4
log4net 2.0.8
This is log4net config:
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Log\App_%date{yyyy-MM-dd}.log" type="log4net.Util.PatternString" />
<appendToFile value="true" />
<param name="maxSizeRollBackups" value="5" />
<rollingStyle value="Composite" />
<datePattern value="yyyy-MM-dd" />
<filter type="log4net.Filter.LevelRangeFilter">
<acceptOnMatch value="true" />
</filter>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%-3thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</log4net>
The very first line in Main(string[] args) is log4net initialization:
XmlConfigurator.ConfigureAndWatch(new FileInfo(AppDomain.CurrentDomain.BaseDirectory + "log4net.config"));
Logger is initialized at the top of Program class like this:
private static readonly ILog _log = LogManager.GetLogger(typeof(Program));
When service is started/restarted or console application is ran manually, log file is created with correct filename, e.g. App_2017-11-29.log. However, if I leave windows service running over night, at midnight new file with initial date is created and old file is appended yesterdays date. So for example, if I start service today, and leave it running for 3 days, this will be in log file
App_2017-11-29.log (current log file)
App_2017-11-29.log2017-12-01
App_2017-11-29.log2017-11-30
App_2017-11-29.log2017-11-29
Any idea why this is happening?
The <file value="" /> element determines the "base" filename and is determined once at application startup, the <datePattern value="" /> is appended after that, and substituted with the current date in the specified format.
So your config should look like this:
<rollingStyle value="Composite" />
<file value="Log\App_" type="log4net.Util.PatternString" />
<datePattern value="yyyy-MM-dd'.log'" />
<staticLogFileName value="false" />
Related
I have an application that is using Anotar.Log4Net for logging. I cannot strip out the Anotar.Log4Net as other team members are using it. I would like to add my own logging file. I added an additional file appender to my app.config called BGDEV. I reviewed the post here to see how other's are accomplishing the task of having two file appenders. The desired behavior below is for each logger to log to it's own file. Everything is logging to MainLog.txt. Is this because there is something wrong with the app.config settings or because I have the anotar library installed?
<log4net>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
<file value="MainLog.txt"/>
<appendToFile value="true"/>
<rollingStyle value="Size"/>
<maxSizeRollBackups value="5"/>
<maximumFileSize value="10MB"/>
<staticLogFileName value="true"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline%exception"/>
</layout>
</appender>
<appender name="BGDEV" type="log4net.Appender.RollingFileAppender">
<file value="BG_Log.txt" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<datePattern value="yyyyMMdd" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true"/>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="FileAppender"/>
</root>
<logger additivity="false" name="BGDev">
<level value="INFO"/>
<appender-ref ref="BGDev" />
</logger>
In code I create a logger and use it. Is there something wrong with my config file or is this becaise I am using
private static readonly ILog otherLog = LogManager.GetLogger("BGDEV");
otherLog.Info("TEST OTHER LOG");
You have a couple of issues with naming in your code and config. Names are case sensitive - you're defining a logger named BGDev, but you call GetLogger("BGDEV"), since no logger named BGDEV exists, it falls back to the root logger.
Your logger named BGDev also references an appender named BGDev, however again, no such appender exists, since you are defining it with an all-uppercase name BGDEV.
Finally, your BGDev logger needs to have a <layout>...</layout> section, or it won't be able to format log messages.
If you fix these issues, it should work as you expect.
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>
I'm currently working on a console C# app and I have to log two type of data :
All steps of the app in general (AppLog)
All information that I get from a service (MachineLog)
MachineLog needs 2 propeties, but when I start the app I do not define them I have some work to do before. But I need to log from start whith AppLog so at le beginning I use :
log4net.Config.XmlConfigurator.Configure();
And it create me the C:\DNC\Suivi\Logs.txt but also C:\DNC\Suivi\(null)\(null)-logs.txt
Is there any way to only load/configure AppLog and later MachineLog ?
I tried to add parameters to Configure() and all failed.
My App.config is :
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="AppLog" />
</root>
<logger name="Machine" additivity="false">
<level value="ALL" />
<appender-ref ref="MachineLog" />
</logger>
<appender name="AppLog" type="log4net.Appender.RollingFileAppender">
<file value="C:\DNC\Suivi\Logs.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<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="MachineLog" type="log4net.Appender.RollingFileAppender" >
<file type="log4net.Util.PatternString" value="C:\DNC\Suivi\%property{Machine}\%property{ID}-logs.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
</configuration>
With your current configuration, you can't do it. As you have seen, log4net will create the log files when XmlConfigurator.Configure() is called.
In order to this, you will have to do at least some work programmatically, once you know where the file will be - it's quite easy to set the file name at runtime so you can have a placeholder file name in the config, then set the correct name at runtime when the values are known. This does mean that the empty placeholder file will exist - the only way around that would be to create the whole appender at runtime.
I have the following config file:
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="D:\log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="20" />
<maximumFileSize value="4MB" />
<staticLogFileName value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
Every line I am logging is written to Console as well, how can I cancel it?
I want it to be appended to the log.txt file ONLY, without anything in Console.
Either you have added console appender programmatically, or this configuration file is not used by log4net. Log4net don't add any default appenders (like default TraceListener in .net). And this configuration specifies only RollingFileAppender. So, verify which configuration file is used, and whether some appenders added in the code.
We are using Log4Net from our ASP.NET MVC3 application, all works fine but we would like to see the current username instead of the application pool's identity in the log files, this is the appender configuration we are using:
<log4net>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
<threshold value="ALL" />
<immediateFlush>true</immediateFlush>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<encoding value="utf-8" />
<file value="C:\Logs\MyLogs.log" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<maxSizeRollBackups value="30" />
<maximumFileSize value="25MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%property{log4net:HostName}] - %username%newline%utcdate - %-5level - %message%newline" />
</layout>
</appender>
<root>
<priority value="ALL" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
So it seems like the property: %username is retrieving the value of:
WindowsIdentity.GetCurrent().Name
Instead of what we would need: HttpContext.Current.User
Any idea on how we can solve this easily in the web.config without creating custom properties or additional log4net derived classes? If possible at all otherwise if custom property is the only way we can live with that I guess :) thanks!
Replacing %username by %identity should do it. It is working for me in my current project.
You can learn more about log4net with this excellent tutorial