log4net: PropertyFilter not working - log4net

I have configured this filter for one of my log4net appenders (uses AdoNetAppender):
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<acceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.PropertyFilter">
<key value="c" />
<stringToMatch value="Stribe.Kernel" />
<acceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
I'm probably doing something really wrong, but been trying to figure it out for an hours now and it's driving me crazy.
What i want the filter to do is deny all entries, except those who's logger name begin (or contain, both fine for me) with "Stribe.Kernel"
Also tried something with but i cannot get it to work.
Any suggestions?

How about you attach the appender to the logger "Stribe.Kernel" instead of the root logger like this:
<root>
<level value="ALL" />
</root>
<logger name="Stribe.Kernel">
<level value="DEBUG" />
<appender-ref ref="YourAppender" />
</logger>
If you are using other loggers you can still attach them to the root logger.

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>

Different levels of logging with 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");

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>

Exiting the logging from an appender

Is it possible to configure so that log4net stops going through the rest of the appenders if an appender got a match?
Something like:
<appender name="TlsReadingAppender" type="log4net.Appender.RollingFileAppender">
<file value="C:\logs\TPOSIn_TlsReading.log" />
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="TPOSIn.ServiceApp.Tls.TlsHandler"/>
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<dontCheckAnyMoreAppenders />
</appender>
You can specify a very long list of appenders but they will only be "Active" if they are referenced in the root tag of your log4net.config file:
<root>
<level value="ERROR" />
<appender-ref ref="fileLogAppender" />
</root>
You could create a list of appenders, using "namespace.class" as the name of the appender to filter the events on each file.
Can you share a bit more about your requirements and what you want to achieve?

How do I use a StringMatchFilter to send logging events to different logs by their message content in log4net?

I'm using log4net for logging and sending e-mails. I need to send different e-mails with different configurations according to different processes. For example, when one of my methods finishes processing, it sends a mail to X, and when my service finishes successfully, it sends another mail to Y.
I think I need to use different appenders with filters, but I can't get to configure them properly.
I tried the following and tried to apply a StringMatchFilter so that messages containing "mandatory" will not be delivered to Y and messages containing "successfully" will not be delivered to X, but with no luck. I am also not sure whether this kind of filtering is the right way to do this kind of configuration.
<log4net>
<appender name="ManFieldMailAppender" type="log4net.Appender.SmtpAppender,log4net">
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="WARN"/>
</evaluator>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="WARN" />
<acceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="successfully" />
<acceptOnMatch value="false" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<to value="x#xxx.com" />
<from value="aaa#aaa.com" />
<subject value="Products not made online" />
<smtpHost value="Host" />
<authentication value="1"/>
<username value="uid" />
<password value="pwd" />
<port value="25"/>
<bufferSize value="1" />
<lossy value="false" />
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%newline %date %message%newline%newline%newline" />
</layout>
</appender>
<appender name="ServiceFinishedMailAppender" type="log4net.Appender.SmtpAppender,log4net">
<evaluator type="log4net.Core.LevelEvaluator">
<threshold value="WARN"/>
</evaluator>
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="WARN" />
<acceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="mandatory" />
<acceptOnMatch value="false" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<to value="y#yyy.com" />
<from value="bbb#bbb.com" />
<subject value="Product Publish Service has successfully finished operating" />
<smtpHost value="Host" />
<authentication value="1"/>
<username value="uid" />
<password value="pwd" />
<port value="25"/>
<bufferSize value="1" />
<lossy value="false" />
<layout type="log4net.Layout.PatternLayout,log4net">
<conversionPattern value="%newline %date %message%newline%newline%newline" />
</layout>
</appender>
<root>
<appender-ref ref="ManFieldMailAppender" />
<appender-ref ref="ServiceFinishedMailAppender"/>
</root>
</log4net>
What do you think the problem is?
Thank you.
First, evaluator tells buffering appenders when to flush. From the look of your configuration I don't think you're buffering. (so you can get rid of the bufferSize and lossy parameters, too). I see your appender filter chains have the required DenyAllFilters. But, your root logger configuration is showing no levels, try adding
<root>
<level value="ALL" />
<!-- appender-refs as normal -->
</root>
In general, I wouldn't make the decision to log to a particular appender based on the message text. It looks like you have a high-level service class for one of the operations. If you have the same thing for the other messages that need to be sent, and you're naming your loggers by typename, you can specify an appender per logger.
<logger name="MyCompany.Product.Whatever">
<level value="WARN" />
<appender name="ManFieldMailAppender" type="...">
<!-- the rest of the configuration, without filtering goes here -->
</appender>
</logger>
<logger name="MyCompany.Services.Publish">
<level value="WARN" />
<appender name="ServiceFinishedMailAppender" type="...">
<!-- the rest of the configuration, without filtering goes here -->
</appender>
</logger>

Resources