Log4Net - 如何正确使用PropertyFilter

时间:2015-12-31 16:09:13

标签: log4net

好的,这是appender:

<appender name="DebugFileAppender" type="log4net.Appender.FileAppender">
  <file value="debug.log" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <filter type="log4net.Filter.PropertyFilter">
    <Key value="ApplicationName" />
    <StringToMatch value="Test Application" />
  </filter>
  <filter type="log4net.Filter.LevelRangeFilter">
    <levelMin value="DEBUG" />
    <levelMax value="DEBUG" />
  </filter>
  <filter type="log4net.Filter.DenyAllFilter" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="Date:%date Thread:[%thread] Level:%-5level Logger:%logger - ApplicationName:%property{ApplicationName}; Message:%message%newline" />
  </layout>
</appender>

现在,它似乎会检查ThreadContext.Properties [“ApplicationName”]字符串,如果找到'Test Application',它会记录。

好吧,即使ApplicationName =“DoNotLog”,它也会记录所有内容。

现在,我将自由地承认这可能是由于我(尝试)使用Log4Net的方式 - 我需要将它暴露给COM,所以我已经包装了一个单独的Log4Net实例,并从COM调用它:

public void LogDebug(LogCodeSource codeSource, LogExecutionSource execSource, object message, Exception exception = null)
    {
        // Add the thread context properties for appender filtering purposes
        log4net.ThreadContext.Properties["ApplicationName"] = codeSource.ApplicationName;
        log4net.ThreadContext.Properties["ComponentName"] = codeSource.ComponentName;
        log4net.ThreadContext.Properties["MethodName"] = codeSource.MethodName;
        log4net.ThreadContext.Properties["ClientMachineName"] = execSource.ClientMachineName;
        log4net.ThreadContext.Properties["ServerMachineName"] = execSource.ServerMachineName;
        log4net.ThreadContext.Properties["UserName"] = execSource.UserName;

        if (exception == null)
        {
            LoggerContext.GetInstance.MainLogger.Debug(message);
        }
        else
        {
            LoggerContext.GetInstance.MainLogger.Debug(message, exception);
        }
    }

在我的测试中,如果我打电话:

var logger = new MyLogger();

logger.LogDebug(new LogCodeSource { ApplicationName = "Test Application", ComponentName = "Test component", MethodName = "Test method" }, new LogExecutionSource { ClientMachineName = "Test client", ServerMachineName = "Test server", UserName = "Test user" }, "Test message");
logger.LogDebug(new LogCodeSource { ApplicationName = "DoNotLog", ComponentName = "Test component", MethodName = "Test method" }, new LogExecutionSource { ClientMachineName = "Test client", ServerMachineName = "Test server", UserName = "Test user" }, "Test message");

在root中,我尝试过:

<root>
  <appender-ref ref="DebugFileAppender" />
</root>

以及:

<logger name="MyLogger">
  <level value="DEBUG" />
  <appender-ref ref="DebugFileAppender" />
</logger>

这两个日志都显示在我的debug.log文件中。

知道为什么属性过滤器不会阻止DoNotLog进入debug.log吗?

以下是我在日志中看到的内容:

Date:2015-12-31 11:11:00,928 Thread:[14] Level:DEBUG Logger:MyLogger - ApplicationName:Test Application; Message:Test message
Date:2015-12-31 11:11:00,942 Thread:[14] Level:DEBUG Logger:MyLogger - ApplicationName:DoNotLog; Message:Test message

2 个答案:

答案 0 :(得分:1)

您所使用的是AND过滤器,因为您要记录ApplicationName与特定名称匹配且级别为DEBUG的所有邮件。很抱歉,log4net不会发货并且过滤器过滤,this SO answer详细说明如何实现。

答案 1 :(得分:0)

如果直接使用log4Net,则使用Microsoft.Extensions.Logging.Abstraction时也可以使用属性过滤器。

示例:

  chart: {
    events: {
      load: function() {
        this.clickedOnce = false;
      },
      click: function() {
        const chart = this;

        if (chart.clickedOnce) {
            chart.zoomOut();
          chart.clickedOnce = false;
        }
      }
    }
  },
  plotOptions: {
    series: {
      events: {
        click: function(e) {
          const chart = this.chart,
            yAxis = chart.yAxis[0],
            xAxis = chart.xAxis[0];

          let x,
            y,
            rangeX,
            rangeY;

          if (!chart.clickedOnce) {
            x = xAxis.toValue(e.chartX);
            y = yAxis.toValue(e.chartY);
            rangeX = xAxis.max - xAxis.min;
            rangeY = yAxis.max - yAxis.min;

            xAxis.setExtremes(x - rangeX / 10, x + rangeX / 10, false);
            yAxis.setExtremes(y - rangeY / 10, y + rangeY / 10, false);
            chart.redraw();

            chart.clickedOnce = true;
          } else {
            chart.zoomOut();
            chart.clickedOnce = false;
          }
        }
      }
    }
  }

然后在配置中必须为属性和键设置一个附加程序。 请注意,如果您想允许一个键包含多个值,则在stringToMacth中有rexexToMatch。

using (_logger.BeginScope(new[] { new KeyValuePair<string, object>("YourPropertyKey", "YourPropertyValue") }))
{
    _logger.LogDebug("My special log with context property set");
}