在 log4net 中,您可以在线程上下文中设置一个属性,该属性将包含在线程的所有日志记录事件中。
public class WcfServiceClass
{
public void ProblemServiceMethod()
{
using (log4net.ThreadContext.Stacks["logThisMethod"].Push("ProblemServiceMethod"))
{
// can also add the correlationId to the logs using this method.
// call business logic...
}
}
}
然后创建一个自定义 appender来过滤它。
public class IfContextSetFilterAppender : log4net.Appender.AppenderSkeleton
{
protected override void Append(LoggingEvent loggingEvent)
{
bool logThisEntry = false;
string serviceMethodBeingLogged;
foreach (object p in loggingEvent.GetProperties())
{
System.Collections.DictionaryEntry dEntry = (System.Collections.DictionaryEntry)p;
if (dEntry.Key == "logThisMethod")
{
logThisEntry = true;
serviceMethodBeingLogged = dEntry.Value.ToString();
}
}
if (!logThisEntry)
return; // don't log it.
// log it.
}
}
这是该想法的非常简单(但清晰)的示例。
如果我真的像您描述的那样将其构建成大规模的服务,我会:
创建一个IOperationInvoker端点行为,该行为获取方法名称并为其应用的所有调用设置 log4net 上下文值。
(可选)让附加程序从 app.config 中读取应记录的所有服务方法名称的过滤器列表。(如果您有选择性地将 OperationInvoker 行为应用于哪些方法,则附加程序不需要这种复杂性。)
通过执行该行为,您可以通过单独的配置来控制生产服务的日志记录,而无需接触服务代码。