Log4Net - flawed LevelRangeFilter. New filter needed.

People seem to have difficulties with getting filters to work in Log4Net.
To even know that there is something called filters for Log4Net takes some digging around to realize. It is not mentioned much in the config examples on the Log4Net site.

I could not get LevelRangeFilter to work as I wanted.
And, as is often the case, the easiest option is to look at the code.
So, after much digging, I succumbed to the inevitable and did a checkout from the Log4Net repository.

It turns out that the logic for LevelRangeFilter is flawed.
And since Log4Net is used everywhere, dont expect the logic to be changed anytime soon.

The main logic for a filter is:
If match: set outcome to what is in AcceptOnMatch and stop processing any more filters. Else: set to Neutral and continue with the next filter below.

The LevelRangeFilter does not addhere to that logic.
Instead its logic is:
If not match: then set outcome to deny.
Else if AcceptOnMatch is true: set outcome to accept.
Else: set outcome to neutral and continue with the next filter.

The solution in my case was to reorder the filters as a workaround for the flawed logic.

So the filters should have looked like this:

      <filter type"log4net.Filter.LevelRangeFilter">
        <levelMin value"INFO" />
        <levelMax value"FATAL" />
        <AcceptOnMatch value"true" />
      </filter>
      <filter type"log4net.Filter.PropertyFilter">
        <key value"MyProperty" />
        <stringToMatch value"cool" />
        <AcceptOnMatch value"true" />
      </filter>
      <filter type"log4net.Filter.DenyAllFilter" />

The log level in the root is set to ALL by the way.

Instead it has to be written:

      <filter type="log4net.Filter.PropertyFilter">
        <key value="MyProperty" />
        <stringToMatch value="cool" />
        <AcceptOnMatch value="true" />
      </filter>
      <filter type="log4net.Filter.LevelRangeFilter">
        <levelMin value="INFO" />
        <levelMax value="FATAL" />
        <AcceptOnMatch value="true" />
      </filter>
      <filter type="log4net.Filter.DenyAllFilter" />

Not very intuitive. This also makes this particular application slightly more inefficient. In this case a log is more likely to have a range between INFO and FATAL than to have have DEBUG level and the MyProperty set to cool. So an extra test is made in most cases that is not needed.

But hey, this is the open source world, so I did my own level filter.
The SaneLevelRangeFilter is available below. Check out Log4Net from the repository, add the file, build.

Digging around the net I found the best site so far that has a couple of Log4Net articles.
The guy also seems to have been bitten by the Arduino bug. All the better :-)
Good source for Log4Net info

/Jonas

story

C# deployment strategy

As I was adding the last touch to an old .NET program of mine I made last year, I thought about deployment of software in general and for deployment for this application in particular.

AttachmentSize
SaneLevelRangeFilter.cs5.65 KB