I have an application that uses log4net. I dump debug to a file as well as stdout.
When launching the application normally, I see all the messages in the output section as well as in the file.
If I create a class/ run a function that writes something to the log in the immediate window, I do not see anything in the Output nor in the Immediate window. I do see the log in the file though.
Is there any way I could fix it so I will be able to see these messages in the Immediate window?
Log4net configuration:
<log4net>
<root>
<level value="DEBUG"/>
<appender-ref ref="FileAppender"/>
<appender-ref ref="ConsoleAppender"/>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss.ffff} [%thread] %level %logger%exception - %message%newline"/>
</layout>
</appender>
<appender name="FileAppender" type="log4net.Appender.RollingFileAppender">
<file value="logs/log.txt" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="1" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss.ffff} [%thread] %level %logger%exception - %message%newline"/>
</layout>
</appender>
</root>
</log4net>
Add a DebugAppender to your configuration in order to have messages appear in the Immediate window (I tested this on VS2013)
<root>
<level value="DEBUG" />
<appender-ref ref="FileAppender" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="DebugAppender" />
</root>
<appender name="DebugAppender" type="log4net.Appender.DebugAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{dd.MM.yyyy HH:mm:ss.ffff} [%thread] %level %logger%exception - %message%newline" />
</layout>
</appender>
Related
I'm trying to get name of the file with log by log4net, but I can't get my Appenders. This is my config:
<log4net>
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="name.log"/>
<appendToFile value="false"/>
<maximumFileSize value="10MB"/>
<maxSizeRollBackups value="0"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %thread %logger - %message%newline"/>
</layout>
</appender>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR"/>
<foreColor value="Red, HighIntensity"/>
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %thread %logger - %message%newline"/>
</layout>
</appender>
<root>
<level value="DEBUG"/>
<appender-ref ref="RollingFileAppender"/>
<appender-ref ref="ColoredConsoleAppender"/>
</root>
</log4net>
This is the code for getting count of appenders:
((Hierarchy)LogManager.GetRepository()).GetAppenders().Length.ToString();
But it gives me 0.
Logging works perfectly, so config works for logging. Do you have any ideas how to get the appenders or file name "name.log" from config without appenders? Thank you.
Is it possible you're fetching the appenders before your call to Configure?
Using the config you provided:
int count;
count = LogManager.GetRepository().GetAppenders().Length; // 0
XmlConfigurator.Configure();
count = LogManager.GetRepository().GetAppenders().Length; // 2
So, I have a console app.
Using log4net to log messages.
Below is my log4net.config file.
<?xml version="1.0"?>
<log4net>
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR" />
<backColor value="Red, HighIntensity" />
</mapping>
<mapping>
<level value="WARN" />
<foreColor value="White" />
<backColor value="Yellow" />
</mapping>
<mapping>
<level value="INFO" />
<foreColor value="White" />
</mapping>
<mapping>
<level value="DEBUG" />
<backColor value="Green" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="ConsoleAppender" />
<appender-ref ref="FileAppender" />
</root>
</log4net>
And in my console app I have this class to run
public class SchedulerService
{
private static readonly ILog _log = LogManager.GetLogger(typeof(SchedulerService));
private readonly SchedulerRegistry _registry;
public SchedulerService(SchedulerRegistry schedulerRegistry)
{
_registry = schedulerRegistry;
}
public void Start()
{
JobManager.Initialize(_registry);
JobManager.JobException += JobManager_JobException;
_log.Info("SchedulerService is started");
}
private void JobManager_JobException(JobExceptionInfo info)
{
Console.WriteLine("An error just happened with a scheduled job: " + info.Exception);
_log.Error("An error just happened with a scheduled job: " + info.Exception);
}
public void Stop()
{
Console.WriteLine("SchedulerService is stopped");
}
}
As a result log.txt file is created but its size is zero, its empty, nothing is logged into that files and nothing is logged to console.
What am I doing wrong?
Thanks a lot.
Your log4net.config is correct.
Make sure:
The Copy to Output Directory property of the log4net.config file is set to Copy Always. This is important because you need the config file to be copied to the bin folder when you build and run your application. Do this by right clicking the config file and select Properties. Then set the value of the Copy to Output Directory property to Copy Always.
You tell log4net to load your config. One way to achieve this is to add the following line to the bottom of your AssemblyInfo file:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config")]
Found the problem :)
Looks like its a new feature of VS 2017 that I haven't noticed before.
Previously you could resolve namespace only if you added corresponding components yourself manually via Add Reference or via NuGet Package Manager.
With VS 2017 when you try to resolve a namespace, it actually installs these packages for you. This maybe convenient, but also frustrating, like in my case.
Don't know why but VS decided to include this Common.Logging & Common.Logging.Core packages instead of log4net that was already in my solution.
Probably I trusted blindly and didn't notice that these packages have nothing to do with the library I wanted to use. The weird thing is that the code compiled just fine :)
So that was the reason why the code wasn't working. Be aware.
Try this method. You have to name it ColoredConsoleAppender instead of ConsoleAppender.Hope it works.
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file value="log.txt" />
<appendToFile value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR"/>
<foreColor value="Red"/>
</mapping>
<mapping>
<level value="INFO"/>
<foreColor value="White"/>
</mapping>
<mapping>
<level value="DEBUG"/>
<foreColor value="Green"/>
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message%newline"/>
</layout>
</appender>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %-5level %logger - %message%newline"/>
</layout>
</appender>
<root>
<priority value="ALL"/>
<appender-ref ref="FileAppender"/>
<appender-ref ref="ColoredConsoleAppender"/>
</root>
I am trying to do something that I thought was simple.
To have a FileAppender in log4net with a date in the filename.
Before you rush to answer this, I need to make clear that I don't need a RollingFileAppender, because I know it's possible with that one.
I want to produce 1 log file every time I run my console app. So I don't need a rolling file appender, just 1 file each time, with a timestamp on it.
This is where it gets tricky because this configuration:
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="MyFileAppender" />
</root>
<appender name="MyFileAppender" type="log4net.Appender.FileAppender">
<file value="logs\" />
<datePattern value="dd.MM.yyyy'.log'" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %level %logger - %message%newline" />
</layout>
</appender>
</log4net>
Gives this error:
log4net:ERROR XmlHierarchyConfigurator: Cannot find Property [datePattern] to se
t object on [log4net.Appender.FileAppender]
It works if I don't have a pattern and just have a static file that keeps getting overriden each time the app.
So is this not possible with a file appender?
I am using version 1.2.15.0.
that did it:
<appender name="FileAppender" type="log4net.Appender.FileAppender">
<file type="log4net.Util.PatternString" value="logs\App-%date{yyyy-MM-dd_HH-mm-ss}.log" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%2thread] %-5level - %message%newline" />
</layout>
</appender>
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 :)
How do I configure log4net or my Gallio test runners (Icarus and Echo) to use a different logging level for the Gallio Execution Log and my own file appender. I want my log file to have a DEBUG log level and Gallio to have an ERROR log level.
I thought this would work but Gallio is reading both appenders:
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
</layout>
</appender>
<appender name="File" type="log4net.Appender.FileAppender">
<file value="test.log" />
<appendToFile value="false" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
</layout>
</appender>
<logger name="TestNamespace">
<level value="DEBUG" />
<appender-ref ref="File" />
</logger>
<root>
<level value="ERROR" />
<appender-ref ref="Console" />
</root>
</log4net>
Gallio is redirecting console output to its Execution Log. So I needed to set the threshold of the ConsoleAppender to the level I want for the Gallio Execution Log.
<log4net>
<appender name="Console" type="log4net.Appender.ConsoleAppender">
<threshold value="ERROR"/>
<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="File" type="log4net.Appender.FileAppender">
<threshold value="DEBUG"/>
<file value="test.log" />
<appendToFile value="false" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%5level [%thread] (%file:%line) - %message%newline" />
</layout>
</appender>
<root>
<appender-ref ref="Console" />
<appender-ref ref="File" />
</root>
</log4net>