Nlog: Custom Filter with no attributes gets skipped by LoggingConfigurationParser in nlog.config

Created on 2 Apr 2019  路  11Comments  路  Source: NLog/NLog

Works in NLog 4.5.11
Does NOT work in NLog 4.6.1

I have a custom filter defined as:

```c#
[Filter(nameof(AuditEventFilter))]
public class AuditEventFilter : WhenContainsFilter
{
public string Dummy { get; set; } // nlog will ignore the filter if this is not set in the nlog.config
protected override FilterResult Check(LogEventInfo logEvent)
{
return Logger.IsAuditEvent(logEvent) ? FilterResult.LogFinal : FilterResult.Ignore;
}
}


I have the following in my nlog.config

```xml
  <rules>
    <logger name="*" minlevel="Debug" writeTo="AuditFileLogger">
      <filters>
        <AuditEventFilter/>
      </filters>
    </logger>

Result: Filter is not recognized and is not added. No error is generated by nlog
If I add and Dummy to my Filter class it works.

The issue appears to be this code in NLogXmlElement.cs which checks to see if the item has attributes and skips, if not:

    IEnumerable<ILoggingConfigurationElement> ILoggingConfigurationElement.Children => Children.Where(item => item.Children.Count > 0 || item.AttributeValues.Count > 0).Cast<ILoggingConfigurationElement>();

Here is a unit test

```c#
private class MyFilter : Filter
{
protected override FilterResult Check(LogEventInfo logEvent)
{
return FilterResult.Neutral;
}
}

    [Fact]
    public void CustomFilterTest()
    {
        ConfigurationItemFactory.Default.Filters.RegisterDefinition(nameof(MyFilter), typeof(MyFilter));
        LoggingConfiguration c = XmlLoggingConfiguration.CreateFromXmlString(@"
        <nlog>
            <targets>
                <target name='d1' type='Debug' />
                <target name='d2' type='Debug' />
                <target name='d3' type='Debug' />
                <target name='d4' type='Debug' />
            </targets>

            <rules>
                <logger name='*' level='Warn' writeTo='d1,d2,d3'>
                    <filters>
                        <MyFilter/>
                        <when condition=""starts-with(message, 'z')"" action='Ignore' />
                    </filters>
                </logger>
            </rules>
        </nlog>");

        Assert.Equal(1, c.LoggingRules.Count);
        var rule = c.LoggingRules[0];
        Assert.Equal(2, rule.Filters.Count);
        var myFilter = rule.Filters[0] as MyFilter;
        Assert.NotNull(myFilter);
        Assert.Equal(FilterResult.LogFinal, myFilter.Action);

        var conditionBasedFilter = rule.Filters[1] as ConditionBasedFilter;
        Assert.NotNull(conditionBasedFilter);
        Assert.Equal("starts-with(message, 'z')", conditionBasedFilter.Condition.ToString());
        Assert.Equal(FilterResult.Ignore, conditionBasedFilter.Action);
    }

```

bug

All 11 comments

Thank you for reporting this. Will take a look.

Created PR: #3271

馃憤 great work, I will try to release NLog 4.6.2 soon.

Thanks for providing an unit test @jonreis 馃憤

@304NotModified my pleasure

--> https://www.nuget.org/packages/NLog/4.6.2 馃帀

(nuget.org is currently indexing)

@304NotModified thank you very much for the quick fix!

Thanks to @snakefoot for the actual fix :)

@snakefoot sorry about that. Thank you for the fix!

Just happy the fix was easy. Was for a moment worried that my refactoring for preparing support for appsettings.json had to be reverted :)

Was this page helpful?
0 / 5 - 0 ratings