Search code examples
log4netlog4net-configurationlog4net-filter

How do I read a list of configuration properties into a custom log4net filter


I am creating a custom filter in log4net. I've found I can map elements in the config to properties in the filter class like this:

<filter type="ConsoleApplication1.CustomFilter">
    <FooKey value="FooValue"/>
</filter>

public class CustomFilter : FilterSkeleton
{
    public string FooKey { get; set; }

    public override FilterDecision Decide(LoggingEvent loggingEvent)
    {
        return FilterDecision.Accept;
    }
}

What I would like to do is set a list of items like this:

<filter type="ConsoleApplication1.CustomFilter">
    <FooKey value="FooValue"/>
    <FooKey value="BarValue"/>
</filter>

public class CustomFilter : FilterSkeleton
{
    public string[] FooKeys { get; set; }

    public override FilterDecision Decide(LoggingEvent loggingEvent)
    {
        return FilterDecision.Accept;
    }
}

If this is possible, how would I do this?


Solution

  • You can find the code responsible for this behavior in the SetParameter method of the XmlHierarchyConfigurator. What transpires is that:

    • If the xml element references a property, then there will be an assignation
    • If the xml element references a method, the method will be called with the xml parameter

    You cannot assign an array from the *.config file since the configurator only handles scalar values. You can however create a method that will push the new parameter to your custom filter:

    public class CustomFilter : FilterSkeleton
    {
        public string[] FooKeys { get; set; }
    
        public override FilterDecision Decide(LoggingEvent loggingEvent)
        {
            return FilterDecision.Accept;
        }
    
        public void AddFooKey(string text)
        {
            var temporaryFooKey = new List<string>(FooKeys ?? new List<string>().ToArray());
            temporaryFooKey.Add(text);
            FooKeys = temporaryFooKey.ToArray();
        }
    }
    

    And then in your configuration file you can do:

    <filter type="ConsoleApplication1.Filters.CustomFilter">
      <FooKey name="AddFooKey" value="FooValue"/>
      <AddFooKey value="BarValue"/>
    </filter>
    

    Please note that if you don't want to change the name of the xml element you can use the name attribute in order to designate what part of the filter must be accessed, and that you can also use directly the method name.