2012-10-15 63 views
6

我一直在寻找WCF服务(包括像NLog和PostSharp的技术)的日志记录,但我有我还没有解决的东西......我不知道我是否缺少有些事情显而易见,或者它不可能。WCF服务,垂直登录

比方说,我有一个WCF服务层和100多个Web服务调用入口点。其中之一造成问题。该层下面是业务逻辑层和数据库层。我想要做的(我认为)打开了该服务调用的日志记录(其中包括相关性的活动ID),以便记录对该服务的任何调用,并记录下层中的所有日志消息。我不想在低层的程序集级别上打开日志记录,因为它们会被许多Web服务方法共享。

这是可能的,通过现有的框架,或通过创造性地使用像CorrelationManager这样的东西?

回答

1

在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... 

     } 
    } 
} 

然后create a custom 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. 
    } 
} 

这是这个想法的非常简单(但清晰)的例子。

如果我象你所说的是真的建设成为为大型这样的服务,我想:

  1. 创建抓起方法名,并设置一个log4net的背景值IOperationInvoker端点行为的所有调用它应用于。

  2. (可选)让appender从app.config中读取应该记录的所有服务方法名称的过滤器列表。 (如果你在被应用到什么方法OperationInvoker行为是有选择性的,在附加器不需要这种复杂性。)

这样做的行为,你有几种选择通过配置单独的生产业务控制记录从未接触过服务代码。

+0

谢谢!这正是我要找的东西。理想情况下,我希望使用NLog over log4net,因为它似乎更加活跃一点,但这正是使我改变主意的事情类型...您是否在愤怒中使用过这样的代码?它将如何处理多线程服务? –

+0

log4net.ThreadContext使用线程本地存储。只要服务调用不跳转线程(read asych),就可以在多线程环境中很好地工作。是的,我已经为真正的生产企业服务做了其中几个。最后一个是在所有日志条目中放置一个关联Id(ThreadContext上的任何东西都可以包含在appender的转换模式中。)log4net不是非常活跃,因为缺少很少的缺失并且扩展它的记录。如果你可以忍受它是在仿制药之前写的,它会很好地对待你。 – ErnieL

+0

谢谢厄尼。那正是我寻找的东西的类型! –

0

您可以为该特定服务调用创建一个新的日志记录源,然后启用诊断程序对其进行过滤。

<system.diagnostics> 
    <sources> 
     <source name="Your.Source.Here" switchValue="Verbose"> 
     <listeners> 
      <add name="xml" /> 
     </listeners> 
     </source> 
    </sources> 
    <sharedListeners> 
     <add name="xml" type="System.Diagnostics.XmlWriterTraceListener" traceOutputOptions="LogicalOperationStack" initializeData="l:\logs\N4S.MSO.ADC.Host.svclog" /> 
    </sharedListeners> 
    </system.diagnostics> 
+0

这是否意味着对下层的日志框架的调用也需要知道源名称? –

+0

克里斯 - 顺便说一句,感谢您的意见;不胜感激! –