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

我已经看到了许多关于伐木的其他问题。最佳做法什么日志平台是最好的。等等这里有一些从这里SO链接到非常好的讨论主题的链接:

logging best practices

log4net vs TraceSource

best logging solution for .NET 3.5 project

.NET 3.5 logging

开始编辑:

键入这个长的职位后,我猜想我正在试图找出的主要事情是如何紧密耦合的WCF记录/跟踪和活动id传播到System.Diagnostics和TraceSources。您可以使用第三方日志记录平台(如log4net或NLog)获取“好”WCF日志记录/跟踪和活动ID传播。如果你这样做,你怎么做?

有关ServiceTraceViewer的几个问题,请参阅这篇文章的底部,

完成编辑。

任何这些职位都没有详细讨论我的问题。我对于日志记录和WCF在做什么感兴趣。如果您正在开发包含WCF服务的项目,并且您已经登录了项目,那么您是否特别使用WCF特定的日志记录功能。特别是,您是否试图整合诸如活动跟踪,活动传播以及端对端跟踪等内容?例如从MSDN的this文章中概述的。 Here是MSDN关于传播活动的另一篇文章。

这些文章做了很好的工作,解释如何使用System.Diagnostics TraceSources进行活动跟踪,活动传播和端到端跟踪。它显示如何配置WCF通过app.config / web.config文件“打开”这些选项。 WCF在内部使用TraceSources来记录通信的结果。

以下是一些示例代码(来自上面链接的第二个MSDN文章),显示或多或少显示如何通过System.Diagnostics和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;

从我看到的所有示例中,通过配置(通常通过app.config)System.Service模型TraceSource并将其propagateActivity属性设置为“true”来实现活动传播。活动实际上通过在Trace.CorrelationManager.ActivityId上设置活动id(guid)进行传播。如果使用log4net或NLog,可以有效地使用WCF日志记录和活动传播吗?

我的项目将非常重要地使用WCF。我们正在努力解决我们的记录解决方案。我认为我非常了解WCF日志记录和活动传播如何与System.Diagnostics和TraceSources一起使用。我想更好地了解如何使用log4net和NLog等日志记录平台实现类似的功能。

他们是否提供一些“本地”支持?它似乎更有可能提供一些基础设施,以便“手动”实现活动传播。也许这样的事情:

//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并且你有日志记录,这里有一些问题:

>你是否使用活动传播?
>您是否使用TraceSources进行日志记录?
>您是否使用其他日志记录平台(例如log4net,NLog)?
>如果您使用其他日志记录平台,您如何进行活动传播?
>您是否使用第三方日志记录(log4net / NLog – 大多数日志记录)和System.Diagnostics.TraceSource(用于WCF服务边界日志记录)的混合?

ServiceTraceViewer怎么样?你用它吗我看到的大多数例子都显示了通过TraceSources和XmlTraceListener由System.Diagnostics生成的输出。它可以消耗log4net,NLog等的输出吗?使用基于TraceSource的日志记录功能是否“最好”?如果是这样,在“WCF服务”边界(捕获一些应用程序上下文以及WCF通信信息)中只需要一点点的基于TraceSource的日志记录就可以在ServiceTraceViewer中查看?我简短地使用了ServiceTraceViewer,就像我正在进行的WCF学习过程一样。

如果你这么远,谢谢阅读。也许我正在反思日志记录,WCF活动传播以及在ServiceTraceViewer中查看日志的能力的整体集成。在选择日志平台和/或日志记录策略时,这似乎是一个重要的考虑因素,但是对于这些日志记录平台或WCF来说,我没有足够的经验来确定。

最佳答案
只是我的镍牌值得,我使用基于AOP的日志记录,我写/维护自己,但它像一些其他日志记录框架…我的基于装饰器,但我可以将其扩展到任何获取在callstack。

所以你有这样的东西:

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
}

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

转载注明原文:使用log4net或NLog进行WCF日志记录/跟踪和活动id传播 - 代码日志