代码之家  ›  专栏  ›  技术社区  ›  wageoghe

使用log4net或NLog的WCF日志记录/跟踪和活动id传播

  •  21
  • wageoghe  · 技术社区  · 14 年前

    我看到了许多关于日志的其他问题。最佳实践。什么样的日志平台最好。等等。这里有一些关于这个话题的非常好的讨论的链接:

    logging best practices

    log4net vs TraceSource

    best logging solution for .NET 3.5 project

    .NET 3.5 logging

    开始编辑:

    有关ServiceTraceViewer的一些问题,请参见本文底部,

    this 来自MSDN的文章。 Here 是MSDN关于传播活动的另一篇文章。

    这些文章很好地解释了如何使用系统诊断跟踪资源。它展示了如何通过配置WCF来“打开”这些选项app.config/网站.config文件。WCF在内部使用TraceSources来记录通信的结果。

    TraceSource ts = new TraceSource("myUserTraceSource");
    Guid oldID = Trace.CorrelationManager.ActivityId;
    Guid traceID = Guid.NewGuid();
    ts.TraceTransfer(0, "transfer", traceID);
    Trace.CorrelationManager.ActivityId = traceID; // Trace is static
    ts.TraceEvent(TraceEventType.Start, 0, "Add request");
    
    double value1 = 100.00D;
    double value2 = 15.99D;
    ts.TraceInformation("Client sends message to Add " + value1 + ", " + value2);
    double result = client.Add(value1, value2);
    ts.TraceInformation("Client receives Add response '" + result + "'");
    
    ts.TraceTransfer(0, "transfer", oldID);
    ts.TraceEvent(TraceEventType.Stop, 0, "Add request");
    Trace.CorrelationManager.ActivityId = oldID;
    

    以下是一种从服务中判断WCF是否已传播活动的方法:

    // Check if an activity was set in scope by WCF, i.e., if it was 
    // propagated from the client. If not, i.e., ambient activity is 
    // equal to Guid.Empty, create a new one.
    if(Trace.CorrelationManager.ActivityId == Guid.Empty)
    {
        Guid newGuid = Guid.NewGuid();
        Trace.CorrelationManager.ActivityId = newGuid;
    }
    // Emit your Start trace.
    ts.TraceEvent(TraceEventType.Start, 0, "Add Activity");
    
    // Emit the processing traces for that request.
    serviceTs.TraceInformation("Service receives Add " 
                            + n1 + ", " + n2);
    // double result = n1 + n2;
    serviceTs.TraceInformation("Service sends Add result" + result);
    
    // Emit the Stop trace and exit the method scope.
    ts.TraceEvent(TraceEventType.Stop, 0, "Add Activity");
    // return result;
    

    从我看到的所有示例来看,活动传播是通过配置实现的(通常是通过应用程序配置)那个系统服务建模TraceSource并将其propagateActivity属性设置为“true”。活动实际上是通过在上设置活动id(guid)来传播的Trace.CorrelationManager.ActivityId. 如果您使用的是log4net或NLog,那么WCF日志记录和活动传播是否可以有效地使用?

    //Inside client code:
    ILog logger = LogManager.GetLogger("client");
    Guid oldActivity = Trace.CorrelationManager.ActivityId;
    if (oldActivity == Guid.Empty)
    {
      Trace.CorrelationManager.ActivityId = Guid.NewGuid();
    }
    
    using (LogManager.NDC.Push(Trace.CorrelationManager.ActivityId))
    {
      log.Info("Before calling WCF Service");
    
      wcfService.Method();
    
      log.Info("After calling WCF Service");
    }
    Trace.CorrelationManager.ActivityId = oldActivity;
    

    如果将log4net/NLog日志记录格式配置为记录NDC堆栈的顶部,则客户端记录的每条消息(当活动在作用域中时)都将被“标记”为活动id。假设WCF服务的实现方式类似,则服务调用期间记录的所有消息也将被记录(尽管,可能在一个单独的文件中),并用相同的活动id标记。因此,可以将“服务”日志文件中的日志消息与“客户端”日志中的相应消息相关联。

    因此,如果您使用WCF并且有日志记录,下面是一些问题:

    1. 你使用活动传播吗?
    2. 您是否使用TraceSources进行日志记录?
    3. 如果您使用另一个日志平台,那么如何进行活动传播?
    4. System.Diagnostics.TraceSource (用于WCF服务边界日志记录)?

    2 回复  |  直到 7 年前
        1
  •  3
  •   jcolebrand    14 年前

    我使用的是我自己编写/维护的基于AOP的日志记录,但它就像其他一些日志框架一样。。。我的基于decorators,但是我可以扩展到调用堆栈上的任何东西。

    using (LogManager.NDC.Push(Trace.CorrelationManager.ActivityId)) {
      log.Info("Before calling WCF Service");
    
      wcfService.Method();
    
      log.Info("After calling WCF Service");
    }
    Trace.CorrelationManager.ActivityId = oldActivity;
    

    如果您在服务器上有类似的东西,那么我的方法在这方面是有效的,但是我的方法在内部日志记录中不是这样的。我的任务是:

    [LogMethod( CaptureDirection = LoggingDirection.InOut /*Optional*/, CaptureVariables = Yes /*Optional*/ )]
    public ClassName MyMethodName(params){
      //magic logging happens here on method entry
    
      DoSomething();
    
      //if you need logging here I can't do anything with my AOP system
    
      DoSomethingElse();
    
    
      //magic logging happens here on method exit
    }
    

    另外,您是否希望在客户机和服务器之间建立相关的日志记录?你怎么和他们谈判?如何确保一个与另一个相关?

        2
  •  0
  •   Michael Freidgeim    11 年前

    这个 article on CodeProject 通过创建customrenderer和listener使用NLog跟踪活动,并指定要在配置中登录的内容。

    Nlog扩展的源代码可以在 http://lowleveldesign.codeplex.com/releases/view/96938