好的,这是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
答案 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");
}