log4net Colored Console Appender issue - c#

I am using log4net library for showing logs on my console ,
I am able to show logs on console when am running the application in debug mode, but when I am running the console through a cmd, it is not showing the logs on console.
XML Config :
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<appender name="RollingFile" type="AutoLogger.FileAppender">
<file type="log4net.Util.PatternString" value="%property{LogFileName}" />
<appendToFile value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<maximumFileSize value="200MB" />
<maxSizeRollBackups value="-1" />
<datePattern value="dd.MM.yyyy'.log'" />
<layout type="AutoLogger.TestcasePatternLayout, AutoLogger">
<conversionPattern value="%level %date %testcase %message (%logger)%newline" />
<param name="Header" value="[TEST START]
" />
<param name="Footer" value="[TEST END]
" />
</layout>
</appender>
<appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<mapping>
<level value="ERROR" />
<foreColor value="White" />
<backColor value="Red" />
</mapping>
<mapping>
<level value="WARN" />
<foreColor value="Yellow" />
</mapping>
<mapping>
<level value="FATAL" />
<foreColor value="White" />
<backColor value="Red, HighIntensity" />
</mapping>
<layout type="AutoLogger.TestcasePatternLayout, AutoLogger">
<conversionPattern value="%level %testcase %message %newline" />
</layout>
</appender>
<root>
<priority value="ALL" />
<appender-ref ref="ColoredConsoleAppender" />
<appender-ref ref="RollingFile" />
</root>
</log4net>

I suspect that I know this one...
You posted some of the XML configuration for log4net, but there is one important bit of info you didn't mention. If you are targeting dotnet core, I can help you out. If you are still targeting the dontnet framework, well, all I can suggest is go back and double check all the online tutorials. I have used the log4net colored console appender for years under the dontnet framework without fail, it works just fine.
On to the main event: If you are working with dotnet core applications, all the other log4net appenders work just fine without any changes from the posted docs and tutorials. For some reason, though, the colored console appender needed to be changed. I dredged this up after quite a bit of digging in the Internet:
<appender name="ColoredConsoleAppender" type="log4net.Appender.ManagedColoredConsoleAppender">
<threshold value="ALL" />
<mapping>
<level value="FATAL" />
<foreColor value="Magenta" />
</mapping>
<mapping>
<level value="ERROR" />
<foreColor value="Red" />
</mapping>
<mapping>
<level value="WARN" />
<foreColor value="Yellow" />
</mapping>
<mapping>
<level value="INFO" />
<foreColor value="Green" />
</mapping>
<mapping>
<level value="DEBUG" />
<foreColor value="Cyan" />
</mapping>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="ColoredConsoleAppender" />
</root>
Just add this to your configuration file as you would any other appender, and it will work just fine.
Bonus points!
Want to define your own set of colors? You cannot use the color names that are from the original colored console appender, it will break. Here is a link to the enumerated values that are legal for the ManagedColoredConsoleAppender:
https://learn.microsoft.com/en-us/dotnet/api/system.consolecolor?redirectedfrom=MSDN&view=net-5.0
May all your logged events be green!

Related

In Log4Net all specified log folders are created but logging is not working for File Appender

I'm using Castle with Log4Net. All folders were created but logging information is not written to a text file.
Here is the config:
<add key="log4net.Internal.Debug" value="true"/>
<add key="log4net.Internal.Error" value="true"/>
<add key="log4net.Internal.Info" value="true"/>
<add key="log4net.Internal.Fatal" value="true"/>
<add key="log4net.Internal.Warn" value="true"/>
<appender name="debugAppender" type="log4net.Appender.RollingFileAppender,log4net">
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="DEBUG" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<file value="..\\..\\LOGS\\DEBUG\\" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<staticLogFileName value="false" />
<DatePattern value="yyyy\\\\MM\\\\dd\\\\yyyyMMdd'_debug.txt'" />
<maxSizeRollBackups value="-1" />
<maximumFileSize value="50MB" />
<countDirection value="1" />
<preserveLogFileNameExtension value="true" />
<encoding value="utf-8" />
<!--<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />-->
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
</appender>`
<logger name="Log">
<appender-ref ref="errorAppender" />
<appender-ref ref="infoAppender" />
<appender-ref ref="debugAppender" />
<appender-ref ref="warningAppender" />
<appender-ref ref="fatalAppender" />
</logger>`
I'm using console application for this, and the Main method will start like this:
XmlConfigurator.Configure(new FileInfo("log4net.config"));
And everyone has permission to write, read all files in LOGS folders.
I used your same configuration of course with little modification which you can try
I created a console application as yours:
Here is my Entry point:
public class Program
{
private static readonly log4net.ILog log
= log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
static void Main(string[] args)
{
XmlConfigurator.Configure(new FileInfo("..\\..\\log4net.config"));
log.Debug("Hi this is DEBUG from logging");
log.Info("This is information from logger");
log.Error("This is Error from logger");
Console.ReadLine();
}
}
And here is the configuration I used:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,
log4net"/>
</configSections>
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender,log4net">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date{ABSOLUTE}
[%thread] %level %logger - %message%newline"/>
</layout>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="DEBUG" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
</appender>
<appender name="debugAppender" type="log4net.Appender.RollingFileAppender,log4net">
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="DEBUG" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<file value="..\\..\\LOGS\\DEBUG\\" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<staticLogFileName value="false" />
<DatePattern value="yyyy\\\\MM\\\\dd\\\\yyyyMMdd'_debug.txt'" />
<maxSizeRollBackups value="-1" />
<maximumFileSize value="50MB" />
<countDirection value="1" />
<preserveLogFileNameExtension value="true" />
<encoding value="utf-8" />
<!--<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />-->
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%date [%thread] %level %logger - %message%newline" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="ConsoleAppender" />
<!--<appender-ref ref="DebugOutputAppender" />-->
<appender-ref ref="debugAppender" />
</root>
</log4net>
</configuration>
You can notice I have added Console appender to check whether the logging is working as expected on the console before checking the log file.
Note: With the same configuration as yours I was not able to log any information in Console as well as file although the folder and the file were getting created without any issues.
The change I did is, added a root level element as pasted in the above configuration snippet.
You need to have one root section to house your top-level logger references. These are the loggers that inherit information from your base logger (root).
I have removed the additional loggers which you have used.
Sometimes you will want to know more about a particular part of your application. log4net anticipated this by allowing you to specify additional logger references beyond just the root logger. For example, here is an additional logger to log to the console messages that occur inside the OtherClass class object:
<logger name="Log4NetTest.OtherClass">
<level value="DEBUG"/>
<appender-ref ref="ConsoleAppender"/>
</logger>
Use it if you are really sure on this.
Good tutorial to start with log4net is here.
Let me know if you face any issues.

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>

Log4Net Class Logger level per Appender-ref

I am trying to separate out a Performance Logger into a separate log using Log4Net...
I setup my new Appender
<appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
<file value="C:\Logs\ServiceLayer.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<datePattern value="_yyyy.MM.dd.lo\g" />
<maximumFileSize value="5MB" />
<maxSizeRollBackups value="10" />
<PreserveLogFileNameExtension value="true" />
<layout type="log4net.Layout.PatternLayout">
<!-- <conversionPattern value="%level %thread %logger - %message%newline" /> -->
<conversionPattern value="%d{yyyy-MM-dd HH:mm:ss.fff} %5level [%thread][%property{bms.log.username}::%property{bms.log.businessRequest}(%property{bms.log.activityLogID})] - %message%newline" />
</layout>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
</appender>
<appender name="PerfFile" type="log4net.Appender.RollingFileAppender">
<file value="C:\Logs\Perf.log" />
<appendToFile value="true" />
<rollingStyle value="Composite" />
<datePattern value="_yyyy.MM.dd-HH-mm.lo\g" />
<maximumFileSize value="5MB" />
<maxSizeRollBackups value="24" />
<PreserveLogFileNameExtension value="false" />
<layout type="log4net.Layout.PatternLayout">
<!-- <conversionPattern value="%level %thread %logger - %message%newline" /> -->
<conversionPattern value="%d{yyyy-MM-dd HH:mm:ss.fff} %5level [%thread][%property{bms.log.username}::%property{bms.log.businessRequest}(%property{bms.log.activityLogID})] - %message%newline" />
</layout>
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
</appender>
The perf appender is the new appender I added...
I also set up a BufferForwardingAppender
<appender name="BMSDefaultAppender" type="log4net.Appender.BufferingForwardingAppender">
<bufferSize value="128" />
<lossy value="false" />
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="WARN" />
</evaluator>
<appender-ref ref="RollingFile" />
From there I set my Root
<root>
<level value="ERROR" />
<appender-ref ref="BMSDefaultAppender" />
</root>
Once I had this setup, I get ERRORs logged to my rolling log file, however I want to capture some info level data into my perf file...
<logger name="BMS.LTD.Activity.Workflow" additivity="false">
<level value="INFO" />
<appender-ref ref="PerfFile" />
</logger>
<logger name="BMS.LTD.Activity.Workflow.Rules" additivity="false">
<level value="WARN" />
<appender-ref ref="PerfFile" />
</logger>
<logger name="BMS.LTD.Persistence.DataSourceDataProviders" additivity="false">
<level value="INFO" />
<appender-ref ref="PerfFile" />
</logger>
<logger name="BMS.LTD.Persistence.DataSourceDataProviders.DataSourceDataCache" additivity="false">
<level value="WARN" />
<appender-ref ref="PerfFile" />
</logger>
I now get my Info and Warn in my Perf log but I also get my errors there too, is it possible to get my ERRORs in my main log and my info levels in my perf logs?
To control what log events get into each file, Add LevelRangeFilters to your appenders:
<!-- log error and above - add to the RollingFile appender config -->
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR"/>
<levelMax value="FATAL"/>
</filter>
and
<!-- log INFO and below - add to the PerfFile appender config -->
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG"/>
<levelMax value="INFO"/>
</filter>

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>
...

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