log4net writes to one file, but should to different - c#

I have two programs: program1 and program2 (they are modules of biggest program and could be run simultaneously), which of them use log4net.dll. Log4net.dll is one and shared between both programs. Each program has its own log configuration. Configurations are only different by logging path.
First path:
"..\Logs\Program1\Log_%date{yyyyMMdd}.log"
Second path:
"..\Logs\Program2\Log_%date{yyyyMMdd}.log"
Here is an example of logging configuration:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="..\Logs\Program1\Log_%date{yyyyMMdd}.log" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger � %message%newline" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
</configuration>
Everything works almost fine, but sometimes program2 writes log to program1 log file. It looks like log4net.dll cached program1 logging settings, and when program2 asked to log, framework uses the same settings. Please suggest, how can I resolve it?

In order for the two programs to write to the same file, you should define loggers for each in their config files.
So, instead of just defining a <root> logger, define a specific logger for Program1 in its config, and the same for Program2 in its config:
<!-- program1.config -->
<appender name="Program1RollingFileAppender"
type="log4net.Appender.RollingFileAppender"> …
<logger name="Program1">
<level value="INFO" />
<appender-ref ref="Program1RollingFileAppender" />
</logger>
<!-- program2.config -->
<appender name="Program2RollingFileAppender"
type="log4net.Appender.RollingFileAppender"> …
<logger name="Program2">
<level value="INFO" />
<appender-ref ref="Program2RollingFileAppender" />
</logger>
Then, in each program, instantiate a logger with the same name, and it will pick up the correct appender:
public class Program1
{
ILog log = LogManager.GetLogger("Program1"); …
public class Program2
{
ILog log = LogManager.GetLogger("Program2"); …

Related

log4net log file is not getting created in C#

log file is not getting created,
using below call to get logger and config file.
is it required to give full path for file?
private static readonly log4net.ILog logger = log4net.LogManager.GetLogger
(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821" requirePermission="false"/>
</configSections>
<!-- Log4net Logging Setup -->
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="50" />
<maximumFileSize value="50MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
</configuration>
Does your code call
log4net.Config.XmlConfigurator.Configure();
on startup?
The <root> section I use has priority, not level:
<root>
<priority value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
(Apparently, that's not the issue https://stackoverflow.com/a/24188507/21336)
after adding below line in AssemblyInfo.cs, could see log file getting created and logs coming.
[assembly: log4net.Config.XmlConfigurator(Watch = true)]

How to configure log4net to log into multiple files

I have a windows service application which is basically a solution created with VS2015 and contains 2 projects.
The first project is dealing with the service itself (start, stop, etc) while the second one is maintaining the process that will be executed due to launch of the service.
I am using the log4net to log messages into a file.
I wanted to created 2 separate log files for each project.
This has been configured into the service project and is up and running.
while it is not working for the second project.
So mainly my question is how to configure log4net to log into different files within one solution?
Configure log4net within the executing project only. If you want log messages from an specific assembly logged to a separate file make sure the root namespace for that assembly is unique and define two log4net appenders, each logging to a separate file and use logging filters to filter by namespace.
<!-- Will log only from the My.Process namespace -->
<appender name="ProcessLog" type="log4net.Appender.RollingFileAppender">
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="My.Process" />
<acceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<file value="process.log" />
<!-- layout, etc -->
</appender>
<!-- will log everything except from the My.Process namespace -->
<appender name="ServiceLog" type="log4net.Appender.RollingFileAppender">
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="My.Process" />
<acceptOnMatch value="false" />
</filter>
<file value="service.log" />
<!-- layout, etc -->
</appender>
And don't forget to add a reference to both appenders in the root element.
Assuming your first and second project have different root namespaces (e.g. Project1.Service and Project2.MaintainProcess), you can use 2 appenders and the logger hierarchy to split the log files by project:
<log4net>
<appender name="Project1Logger" type="log4net.Appender.RollingFileAppender">
<file value="Project1Logger.log" />
</appender>
<appender name="Project2Logger" type="log4net.Appender.RollingFileAppender">
<file value="Project2Logger.log" />
</appender>
<root>
<level value="ALL" />
</root>
<logger name="{Project1RootNamespaceHere}">
<appender-ref ref="Project1Logger" />
</logger>
<logger name="{Project2RootNamespaceHere}">
<appender-ref ref="Project2Logger" />
</logger>
</log4net>
If you don't want to use separate appenders and logger hierarchy then see this answer for an alternative method using a custom pattern substitution to use a single appender. I'm not sure of the performance implications of that approach though.
Complete configuration (with a MinimalLock file appender):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<log4net>
<!-- ALL, DEBUG, INFO, WARN, ERROR, FATAL, OFF -->
<appender name="RollingFileAppender_Info" type="log4net.Appender.RollingFileAppender">
<file value="Info.log" />
<encoding value="utf-8" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100MB" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message %exception%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="WARN" />
</filter>
</appender>
<appender name="RollingFileAppender_Error" type="log4net.Appender.RollingFileAppender">
<file value="Error.log" />
<encoding value="utf-8" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="100MB" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message %exception%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender_Info" />
<appender-ref ref="RollingFileAppender_Error" />
</root>
</log4net>
</configuration>

How to use log4net with Nunit?

I have a DLL class that create log4net log:
[SetUpFixture]
public class Application
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
[SetUp]
private Application()
{
log4net.Config.BasicConfigurator.Configure();
ILog log = log4net.LogManager.GetLogger(typeof(Application));
log.Debug("This is a debug message");
log.Warn("This is a warn message");
}
}
and Log4Net.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821" />
</configSections>
<!-- Log4net Logging Setup -->
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender,log4net">
<file value="c:\\mylogfile.txt" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="FileAppender"/>
</root>
</log4net>
</configuration>
My program starts the nunit.exe by:
string nunitAppPath = #"C:\Program Files (x86)\NUnit 2.6.4\bin\nunit.exe";
Process.Start(new ProcessStartInfo(nunitAppPath));
and have a reference to DLL.
I have a text file in c name :mylogfile.txt, but it's always null.

log4net creates log file but does not write to it

I am trying to use basic logging for a windows service.
I added the reference to log4net.
I added the following in AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
I added the following to my App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821" requirePermission="false" />
</configSections>
<!-- Log4net Logging Setup -->
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
<file value="c:\\CGSD\\log\\logfile.txt" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="FATAL" />
</filter>
</appender>
<root>
<level value="ALL"/>
<appender-ref ref="RollingFileAppender"/>
</root>
</log4net>
</configuration>
I have the following code in my service:
log4net.Config.XmlConfigurator.Configure();
log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
log.Debug("test");
The file c:\CGSD\log\logfile.txt is created but nothing is ever written to it.
I've been through the forums all day trying to track this one down, but if I overlooked an already posted solution I apologize.
Your filter level looks to be configured at <levelMin value="INFO" /> but you are testing a log.Debug message. Change your configuration to have <levelMin value="DEBUG" /> and try again. If that doesn't fix it, there may be other config problems also.
You require a minimum level INFO and are trying to log a message with level DEBUG. As you can see in the documentation (http://logging.apache.org/log4net/release/manual/introduction.html), the priority of DEBUG is lower than INFO so your message is filtered out.

Log4net inside BHO does not work?

I'm trying to use log4net with an external config file, but it does not work: nothing gets logged
<?xml version="1.0" encoding="utf-8" ?>
<log4net>
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="C:\\tmp\\test.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>
<appender-ref ref="RollingFile" />
</root>
</log4net>
If I use this line in Assembly.cs, test.lg is creatd when the BHO is registered with regasm, but not when the plugin is running:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = #"C:\\tmp\\test.log4net", Watch = true)]
When I use this code inside the BHO, no log is adde to test.log:
XmlConfigurator.Configure(new System.IO.FileInfo(#"C:\\tmp\\test.log4net"));
log.Info("test");
I'm not sure what I am doing wrong.
The log4net configuration file was fine. The problem is that Internet Explorer ran in Protected Mode, which forbids BHOs to write to arbitrary folders. There are only a few folders where the BHO can write.

Categories