wag*_*ghe 21 wcf logging log4net system.diagnostics nlog
我在日志记录中看到了许多其他问题.最佳做法.什么日志记录平台最好.等等.这里有一些关于SO的链接以及关于该主题的非常好的讨论:
开始编辑:
键入这篇长篇文章后,我想我想弄清楚的主要是WCF日志/跟踪和活动ID传播与System.Diagnostics和TraceSources的紧密耦合.您是否可以使用第三方日志记录平台(如log4net或NLog)获得"良好"的WCF日志记录/跟踪和活动ID传播.如果你这样做,你怎么做?
有关ServiceTraceViewer的一些问题,请参阅本文的底部,
结束编辑.
我的问题的主题在任何这些帖子中都没有详细讨论.我对人们在日志记录和WCF方面做了什么感兴趣.如果您正在处理包含WCF服务的项目并且已登录项目,那么您是否需要特别努力来使用特定于WCF的日志记录功能.特别是,您是否尝试合并活动跟踪,活动传播和端到端跟踪等内容?如MSDN 中的这篇文章所述. 这是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;
Run Code Online (Sandbox Code Playgroud)
以下是一种可以在服务中告知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;
Run Code Online (Sandbox Code Playgroud)
从我看到的所有示例中,实现了活动传播(通常通过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;
Run Code Online (Sandbox Code Playgroud)
如果将log4net/NLog日志记录格式配置为记录NDC堆栈的顶部,则客户端记录的每条消息(当活动在范围内时)将使用活动ID"标记".假设WCF服务的实现类似,那么在服务调用期间记录的所有消息也将被记录(尽管可能在单独的文件中)并标记有相同的活动ID.因此,可以将"服务"日志文件中的日志消息与"客户端"日志中的相应消息相关联.
所以,如果你使用WCF并且你有日志记录,这里有一些问题:
System.Diagnostics.TraceSource(用于WCF服务边界日志记录)?那么ServiceTraceViewer呢?你用它吗?我见过的大多数示例都显示了System.Diagnostics通过TraceSources和XmlTraceListener生成的输出.它可以消耗log4net,NLog等的输出吗?基于TraceSource的日志记录是否"最佳"?如果是这样,在WCF服务边界(捕获一些应用程序上下文以及WCF通信信息)只需要一点基于TraceSource的日志记录,以便在ServiceTraceViewer中查看,这是否"足够好"?我简要地使用了ServiceTraceViewer,这是我正在进行的WCF学习过程的一部分.
如果你走到这一步,感谢阅读.也许我正在过度思考日志记录,WCF活动传播的整体集成以及在ServiceTraceViewer中查看日志的能力.在选择日志记录平台和/或日志记录策略时,这似乎是一个重要的考虑因素,但我没有足够的经验来使用这些日志记录平台或WCF来确定.
只是我的镍值,我使用我自己编写/维护的基于 AOP 的日志记录,但它就像其他一些日志记录框架一样......我的框架基于装饰器,但我可以将其扩展到调用堆栈上的任何内容。
所以你有这样的东西:
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;
Run Code Online (Sandbox Code Playgroud)
如果服务器上有类似的东西,那么我的方法可以在这方面起作用,但我的方法不适用于内部日志记录。我的设置是为了执行此操作:
[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
}
Run Code Online (Sandbox Code Playgroud)
此外,您是否希望在客户端和服务器之间建立关联的日志记录?这两个人如何谈判?您如何确保其中一个与另一个相关?