How to AND log4net filters together

16.1k views Asked by At

I would like to create an appender that logs only for a particular level AND only for a particular logger. From what I'm seeing, and based on this tutorial, the filters are ORed together. How can I AND the log4net filters together? Here's an example of what I'm doing:

<appender name="MyAppender">
      <!--log only INFO level-->
      <filter type="log4net.Filter.LevelMatchFilter">
          <levelToMatch value="INFO" />
      </filter>

      <!--log only UserController logger-->
      <filter type="log4net.Filter.LoggerMatchFilter">
        <loggerToMatch value="MyLogger" />
      </filter>

      <!-- do not log anything else -->
      <filter type="log4net.Filter.DenyAllFilter" />
</appender>
3

There are 3 answers

1
Narayan Akhade On BEST ANSWER

You can write a custom AndFilter, which is fairly easy. You can use the code posted here - https://stackoverflow.com/a/8859037/984438

Usage will be like:

<filter type="Namespace.AndFilter, Assembly">
      <!--log only INFO level-->
      <filter type="log4net.Filter.LevelMatchFilter">
          <levelToMatch value="INFO" />
      </filter>

      <!--log only UserController logger-->
      <filter type="log4net.Filter.LoggerMatchFilter">
        <loggerToMatch value="MyLogger" />
      </filter>
      <acceptOnMatch value="true"/>
</filter>
<!-- do not log anything else -->
<filter type="log4net.Filter.DenyAllFilter" />
0
Alex On

Workaround

I just came up with the following workaround that seems to do the trick. First, I removed the loggerToMatch filter from the appender. Then I modified the logger settings as such:

<root>
      <level value="ALL" />
      <appender-ref ref="OtherAppenders" />
</root>

<logger name="MyLogger">
      <level value="INFO" />
      <appender-ref ref="MyAppender" />
</logger>

Since I only have one filter my filter logic is fine. The logger section points to this appender only for my chosen logger, yet all the other appenders pick up the event as well because they're specified in the root. This works but it doesn't explain how to AND the filters together in the appender. I would still like to know.

0
Rashack On

You could use ForwardingAppender (see Config examples) and put one filter there and the other in your target appender (or chain them at will).

<appender name="FilterOnlyInfo" type="log4net.Appender.ForwardingAppender">
  <!--log only INFO level-->
  <filter type="log4net.Filter.LevelMatchFilter">
      <levelToMatch value="INFO" />
  </filter>
  <appender-ref ref="FinalAppender" />
</appender>
<appender name="FinalAppender">
  <!--log only UserController logger-->
  <filter type="log4net.Filter.LoggerMatchFilter">
    <loggerToMatch value="MyLogger" />
  </filter>
</appender>

I believe this appender might not have been part of log4net at the time of the question.