Discarding several log levels within a range with log4net - log4net

Say I set my log4net logger's minLevel and maxLevel to FATAL and DEBUG respectively, but under some scenario I want to mute the log-items written in the WARN level, and keep all the other levels in the range active.
Is it possible to somehow use 'discrete' levels of log-levels rather than specifying a range using minLevel and maxLevel?
I assume this should be simple, but I haven't found any log4net docs or examples dealing with this issue.

You can use the LevelMatchFilter on your appender.
Example:
<appender name="FilteredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="DEBUG" />
</filter>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="INFO" />
</filter>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="ERROR" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
...
</appender>
This example will only print DEBUG; INFO and ERROR messages. It is easy to customize this according to your needs.
Note: Do not forget the DenyAllFilter at the end.

It's cool how log4net filters can all be combined to achieve the desired output. All log entries by default have a "Neutral" filter disposition and log4net by default logs all entries that are neutral.
What the LevelRangeFilter will do is if the level of the entry is in the range, it will set the filter disposition to "Accept" (or leave its disposition as it was if the acceptOnMatch parameter is set to false) and it will mark all entries not in the range with a disposition of "Deny".
The LevelMatchFilter will set the disposition for the filter specified in the levelToMatch parameter to "Accept" unless the acceptToMatch is set to false, then it will set matching entries to "Deny", unmatched entries will be left to what they were before.
So what you can do is use a combination of the two filters to get what you want:
<appender name="FilteredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMax value="FATAL" />
<levelMin value="ERROR" />
</filter>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="WARN" />
<acceptOnMatch value="false" />
</filter>
</appender>
This will allow you to easily toggle the warn level on and off. All entries outside of the range are already all marked as "Deny" and the LevelMatchFilter here will mark WARN level entries to Deny as well so the DenyAllFilter is not required.

Use LevelRangeFilter
<filter type="log4net.Filter.LevelRangeFilter">
<levelMax value="FATAL" />
<levelMin value="ERROR" />
</filter>

Related

filter log levels including custom level [duplicate]

Say I set my log4net logger's minLevel and maxLevel to FATAL and DEBUG respectively, but under some scenario I want to mute the log-items written in the WARN level, and keep all the other levels in the range active.
Is it possible to somehow use 'discrete' levels of log-levels rather than specifying a range using minLevel and maxLevel?
I assume this should be simple, but I haven't found any log4net docs or examples dealing with this issue.
You can use the LevelMatchFilter on your appender.
Example:
<appender name="FilteredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="DEBUG" />
</filter>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="INFO" />
</filter>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="ERROR" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
...
</appender>
This example will only print DEBUG; INFO and ERROR messages. It is easy to customize this according to your needs.
Note: Do not forget the DenyAllFilter at the end.
It's cool how log4net filters can all be combined to achieve the desired output. All log entries by default have a "Neutral" filter disposition and log4net by default logs all entries that are neutral.
What the LevelRangeFilter will do is if the level of the entry is in the range, it will set the filter disposition to "Accept" (or leave its disposition as it was if the acceptOnMatch parameter is set to false) and it will mark all entries not in the range with a disposition of "Deny".
The LevelMatchFilter will set the disposition for the filter specified in the levelToMatch parameter to "Accept" unless the acceptToMatch is set to false, then it will set matching entries to "Deny", unmatched entries will be left to what they were before.
So what you can do is use a combination of the two filters to get what you want:
<appender name="FilteredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMax value="FATAL" />
<levelMin value="ERROR" />
</filter>
<filter type="log4net.Filter.LevelMatchFilter">
<levelToMatch value="WARN" />
<acceptOnMatch value="false" />
</filter>
</appender>
This will allow you to easily toggle the warn level on and off. All entries outside of the range are already all marked as "Deny" and the LevelMatchFilter here will mark WARN level entries to Deny as well so the DenyAllFilter is not required.
Use LevelRangeFilter
<filter type="log4net.Filter.LevelRangeFilter">
<levelMax value="FATAL" />
<levelMin value="ERROR" />
</filter>

Log4Net - WIll it be good to comment out the appneders

In my application I have a separate file appender for Errors and (Info and Debug). In production I just want to log the errors and disable the information and debug logs. Will keeping the appenders good way to do it, considering the performance in mind, or will it be bad for performance
Keep the appenders but change the log level value to WARN inside the "root" tag
<level value="WARN" />
<appender-ref ref="FILE.ERROR" />
<appender-ref ref="FILE.INFO" />
Comment out the information appender from the "root" tag
<level value="WARN" />
<appender-ref ref="FILE.ERROR" />
<!--<appender-ref ref="FILE.INFO" />-->
My logic says #2 is better because if we keep it enabled (as in #1) Log4net will initialize the appender, then for every log statement it will then compare the log level from the log statement vs the log level allowed by the appender and then take decision to log it or not. By using#2 we can avoid this loop and extra execution as the information appender will not be initialized at all.
My information appender has log level set as
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
<levelMax value="INFO" />
</filter>
My question is my understanding from performance point of view valid? Or, it doesn't really matter for log4net, or may be log4net will not initialize the information appender as its log level does not match the root logger level viz. WARN

How to make log4net.Filter.StringMatchFilter work with acceptOnMatch set to false

I've just started using log4net and have some issues with filtering using strings.
I'm trying to remove EPiServer specific logging in my log4net log file as I am not interested in it.
I have the following log4net configuration for an appender:
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="DEBUG" />
</filter>
<filter type="log4net.Filter.StringMatchFilter">
<stringToMatch value="EPiServer" />
<acceptOnMatch value="false" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
I only have one root logger. This config does not stop the EPiServer logging.
What am I doing wrong?
Try changing your StringMatchFilter to a LoggerMatchFilter
<filter type="log4net.Filter.LoggerMatchFilter">
<loggerToMatch value="EPiServer" />
<acceptOnMatch value="false" />
</filter>
A StringMatchFilter filters on the content of the log message, where a LoggerMatch filters on the Logger's class Name or partial Namespace
You should remove the line
<filter type="log4net.Filter.DenyAllFilter" />
From the docs:
You can add this filter to the end of a filter chain to switch from
the default "accept all unless instructed otherwise" filtering
behavior to a "deny all unless instructed otherwise" behavior.
Which effectively reverses the logic to deny all messages unless explicitly whitelisted inside a <filter> using <acceptOnMatch value="true" />

Log4net filter and replace the log message?

Can log4net filter and replace matched log message?
<filter type="log4net.Filter.StringMatchFilter">
<param name="AcceptOnMatch" value="false" />
<param name="RegexToMatch" value="<Code>.*</Code>" />
</filter>
This code can match the ...content...of Code and not to write all message to file.
But, what I want is that save the message, and replace the content of Code with empty.
Thanks.
Never heard of such functionality in bundled filters.
You'll probably have to do the job yourself by subclassing log4Net.Filter.FilterSkeleton or StringMatchFilter.
Then in your XML, you'll only have to call
<filter type="Your.Application.TheFilterYouJustWrote">
<param name="AcceptOnMatch" value="false" />
<param name="RegexToMatch" value="<Code>.*</Code>" />
</filter>

How to filter by NDC?

In log4net I want to filter log messages by the value of the NDC like this:
<filter type="log4net.Filter.PropertyFilter">
<Key value="NDC" />
<stringToMatch value="MyContext" />
</filter>
Somehow the above filter is not working like I expected.
How do I have to configure a filter for my appender that will only match a certain NDC?
I just found the solution. I forgot to filter out the non matching events by adding the following line:
<filter type="log4net.Filter.DenyAllFilter" />

Resources