Different levels of logging with log4net - log4net

I must log some methods. In one method I must log everything. In all others method I've just log exception...
I have done this configuration:
<log4net>
<appender name="OneMethodFileAppender" type="log4net.Appender.RollingFileAppender">
...
<filter type="log4net.Filter.PropertyFilter">
<key value="realMethod" />
<stringToMatch value="xxx" />
<acceptOnMatch value="true" />
</filter>
</appender>
<appender name="WebsiteFileAppender" type="log4net.Appender.RollingFileAppender">
...
<filter type="log4net.Filter.PropertyFilter">
<key value="realMethod" />
<stringToMatch value="xxx" />
<acceptOnMatch value="false" />
</filter>
</appender>
<root>
<appender-ref ref="WebsiteFileAppender">
<threshold value="ERROR" />
</appender-ref>
<appender-ref ref="OneMethodFileAppender">
<threshold value="INFO" />
</appender-ref>
</root>
</log4net>
So, when I match the property realMethod I should use the appender OneMethodFileAppender that log at the INFO level; in all other cases i should use the appender WebsiteFileAppender that log at ERROR level.
I have a different output.
1. When i match the method xxx everything works correctly. I mean that a log at INFO level in the correct log.
2. But when I do not match the method xxx, I log in both files and both at INFO level.

I would suggest to use the logger element to configure your logging:
<log4net>
<appender name="OneMethodFileAppender" type="log4net.Appender.RollingFileAppender">
...
</appender>
<appender name="WebsiteFileAppender" type="log4net.Appender.RollingFileAppender">
...
</appender>
<root>
<appender-ref ref="WebsiteFileAppender">
<threshold value="ERROR" />
</appender-ref>
</root>
<logger name="LoggerName1">
<level value="INFO" />
<appender-ref ref="WebsiteFileAppender" />
</logger>
<logger name="LoggerName2">
<level value="INFO" />
<appender-ref ref="OneMethodFileAppender" />
</logger>
</log4net>
Both methods should have there own logger:
logger = LogManager.GetLogger("logger1");

Related

How to enable and disable log4Net log levels?

I am trying to setup the log4net configuration in my Dot Net Core C# library. I have configured the following log levels. But I want to enable and disable the log levels independently.
<root>
<level value="Info" />
<level value="Warn" />
<level value="Error" />
<level value="Fatal" />
<level value="Debug" />
<appender-ref ref="LogFileAppender" />
</root>
For example, how can I disable and enable the Debug flag by setting it to true or false?
Something like
<level value="Debug" Enable = "True"/>
I think there is some settings, but I don't remember. Thanks for your help to fix this issue.
But I want to enable and disable the log levels independently.
You can't.
The levels are not independent but ordered as follows
ALL
DEBUG
INFO
WARN
ERROR
FATAL
OFF
So when you set your logging level you automatically include messages for that level and all lower levels.
E.g. If you set your level to Debug you also get Info,Warn, Error and Fatal messages and if your set your level to Info, you also get Warn, Error and Fatal messages etc
You'll have to apply a LevelMatchFilter on the appender, which filters on the exact match of the specified level. You can combine multiple filters in case you want to log more than 1 specific level.
Note that you have to end with a DenyAllFilter to block the other levels.
An example, given these log statements
logger.Debug("Debug");
logger.Info("Info");
logger.Warn("Warn");
logger.Error("Error");
logger.Fatal("Fatal");
When you apply the configuration below, only the message Debug will be logged.
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="DEBUG" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message%newline" />
</layout>
</appender>
<root>
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>
When you want to log 2 levels, e.g. only error and info, then you combine the filters as shown here.
The log output will be Info and Error.
<log4net>
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="ERROR" />
</filter>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="INFO" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%message%newline" />
</layout>
</appender>
<root>
<appender-ref ref="ConsoleAppender" />
</root>
</log4net>

How to define different logger levels per appenders

I'm trying to define 2 independent appenders to log into to 2 files. I define
DEBUG level for the "DebugAppender" and then for the "RelevantAppender" I define different levels for the "Security" and "ServerStats" loggers.
The thing is that these loggers definitions are overwriting my "DebugAppender" levels and now it's not in DEBUG mode (all the loggers).
How can make it work as expected?
<log4net>
<appender name="DebugAppender" type="log4net.Appender.RollingFileAppender">
<file value="plastic.debug.log.txt" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value=".yyyyMMdd" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %thread %property{TransactionID} %property{ClientMachine} %-5level %logger - %message%newline" />
</layout>
</appender>
<appender name="RelevantAppender" type="log4net.Appender.RollingFileAppender">
<file value="plastic.relevant.log.txt" />
<appendToFile value="true" />
<rollingStyle value="Date" />
<datePattern value=".yyyyMMdd" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date %property{ClientMachine} %-5level %logger - %message%newline" />
</layout>`enter code here`
</appender>
<logger name="Security">
<level value="ERROR" />
<appender-ref ref="RelevantAppender" />
</logger>
<logger name="ServerStats">
<level value="INFO" />
<appender-ref ref="RelevantAppender" />
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="DebugAppender" />
</root>
You're problem is, that the definition you make in Logger outweights all following levels. So here comes my solution:
<log4net>
<appender name="DebugAppender" type="log4net.Appender.RollingFileAppender">
<file value="plastic.debug.log.txt" />
<!--...-->
</appender>
<appender name="Security_RelevantAppender" type="log4net.Appender.RollingFileAppender">
<threshold value="ERROR" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<file value="plastic.relevant.log.txt" />
<!--...-->
</appender>
<appender name="Serverstat_RelevantAppender" type="log4net.Appender.RollingFileAppender">
<threshold value="INFO" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<!--...-->
</appender>
<logger name="Security">
<appender-ref ref="Security_RelevantAppender" />
</logger>
<logger name="ServerStats">
<appender-ref ref="Serverstat_RelevantAppender" />
</logger>
<root>
<level value="DEBUG" />
<appender-ref ref="DebugAppender" />
</root>
</log4net>
Define 3 different appenders. The DebugAppender's level is defined by <root>. The two relevant appenders write both to the same file with different log-levels (thresholds). It is important, that you include the locking model <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />. Utherwise the first appender you call will lock the file and the second one can not write in it (Can Log4net have multiple appenders write to the same file?). In the <logger> you just define the two different appenders and no loglevel. This way it will take the level from the appender settings.
When you do it like this all events of the type debug+ from any logger will be written to plastic.debug.log.txt. To plastic.relevant.log.txt only events error+ from security-logger and info+ from serverstat-logger are written.
Hope this helps

What's wrong with my log4net config file

I have a config file with two appenders, one file appender and one database appender. I want to log everything to the file appender, and only log exceptions to the database appender. When setting up both appenders in the section it logs fine but all log events are sent to both appenders, which is not what i want.
I changed the configuration but with this current configuration, exceptions get logged to the database, and nothing is getting written to the file appender. Can anyone tell me why I am not getting anything written to the file appender?
<log4net debug="true">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\Log4net\Workflow\TestLog.txt" />
<threshold value="All" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10KB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5p {%logger} %d %5rms %-22.22c{1} %-18.18M - %m%n" />
</layout>
</appender>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<!-- Removed to keep this snippet simple-->
</appender>
<root>
<level value="Error" />
<appender-ref ref="AdoNetAppender" />
</root>
<logger name="AllLogs">
<level value="ALL" />
<appender-ref ref="RollingLogFileAppender" />
</logger>
</log4net>
What you have here is the following:
all logs events with the level Error or more will go to the AdoNetAppender
all logs events originating from a logger whose name is based on AllLogs will go to the RollingLogFileAppender
From what I understand you want all logs to default to the file, and only error ones to go also to the database. Then simply add both appenders to your root logger so that both get all events, and add filters to only let filters you're interested in pass through: a level range filter on your database appender would work
<log4net debug="true">
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<!-- rest of config snipped to save space -->
</appender>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<levelMax value="FATAL" />
</filter>
<!-- rest of config snipped to save space -->
</appender>
<root>
<appender-ref ref="AdoNetAppender" />
<appender-ref ref="RollingLogFileAppender" />
</root>
</log4net>
Of course if you don't want any duplicate just filter errors and above in the rolling file appender

log4net RollingFileAppender rollingstyle on both date and level

been scratching my head to get rolling style on both date and level for log4net.
what i'm trying to achieve is this:
on 1st Jan:
2014-01-01_DEBUG.txt
2014-01-01_INFO.txt
2014-01-01_ERROR.txt
on 2nd Jan:
2014-01-02_DEBUG.txt
2014-01-02_INFO.txt
2014-01-02_ERROR.txt
The easiest way to achieve this would be to create one RollingFileAppender for each level and filter each appender to pick only one level:
<appender name="DebugAppender" type="log4net.Appender.RollingFileAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="DEBUG" />
</filter>
<!-- ... -->
<appender name="InfoAppender" type="log4net.Appender.RollingFileAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="INFO" />
<levelMax value="INFO" />
</filter>
<!-- ... -->
And then simply plug them all into the logger you need
<root>
<level value="DEBUG" />
<appender-ref ref="DebugAppender" />
<appender-ref ref="InfoAppender" />
<appender-ref ref="ErrorAppender" />
</root>

Log4Net: Multiple loggers

I have the following log4net configuration:
<log4net>
<appender name="A1" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="C:\path1.log" />
</appender>
<appender name="A2" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="C:\path2.log" />
</appender>
<logger name="A1Logger">
<level value="ALL" />
<appender-ref ref="A1" />
</logger>
<logger name="A2Logger">
<level value="ALL" />
<appender-ref ref="A2" />
</logger>
</log4net>
and then in code I do the following:
var logger1 = LogManager.GetLogger("A1Logger");
var logger2 = LogManager.GetLogger("A2Logger");
but both log to the same file C:\path1.log.
What am I doing wrong?
Add the debug="true" attribute to the <log4net> element, my guess is that it is the missing <root> element that causes problems. You should always include the <root /> logger element.
Seems that it was a weird debugging error. Right now it doesn't reproduce. My apologies.

Resources