2016-02-01 58 views
0

我在我的项目中使用nlog记录器。使用nlog记录多个线程

我的程序根据我从sql server获得的数据生成xml文件。我正在用PLINQ来做这件事。但是我也必须记录跟踪信息,以便能够对产品环境中的特殊情况进行一些调查。

当它来自多个线程时,结果日志看起来很糟糕。例如:

Operation 1 starded 
Deserializing XXX 
Operation 2 started 
Deserializing XXX finished with status X 
Filling XXX with data from Z 
Deserializing YYY.... 

而且它只是为并行度2.

我想看到的结果是这样的:

Operation 1 starded 
Deserializing XXX 
Deserializing XXX finished with status X 
Filling XXX with data from Z 
Operation 1 finished 
Operation 2 started  
Deserializing YYY.... 

我看到一些解决方案,但他们没有看起来不够好:

  1. 将日志数据保存到某个缓冲区并在parralel任务结束时将其刷新 - 我将应该将上下文传递给所有内部方法(看起来很可怕!)。
  2. 添加某种preffix记录消息,以帮助获取某些消息的上下文 - 我必须将preffix传递给每个内部消息(也看起来很糟糕)。

有没有一些干净的解决方案,这个问题?

+0

我认为记录事件的实际顺序对于错误检测实际上可能是有价值的,因为多线程环境中的典型错误当然是某些意料之外的事件顺序。但是为什么不在日志消息前添加一个线程名称/ ID?日志记录可以通过线程中的接口(无论如何这是一个好主意)引导,这可以将前缀添加到实际消息中。这样,您可以始终对日志进行后期处理,以便一起查看与特定线程相关的所有消息。 –

+0

我认为缓冲是一种值得怀疑的记录策略,因为导致灾难性错误的事件可能永远不会写入日志。 –

+0

你可以将所有的日志写入并发队列,然后在不同的线程上出队? – Enigmativity

回答

5

在NLOG配置文件中有${threadid}语法。使用这样的:

   <target name="file" xsi:type="File" 
       layout="${longdate} [${threadid}] ${level:uppercase=true} ${message} ${exception:format=tostring}" 
       fileName="${basedir}/logs/log.txt" 
       archiveFileName="${basedir}/logs/log.{#####}.txt" 
       archiveAboveSize="10485760" 
       archiveNumbering="Sequence" 
       concurrentWrites="true" 
       keepFileOpen="false" /> 

更多信息:

https://github.com/NLog/NLog/wiki/ThreadId-Layout-Renderer

我在生产中使用和generaly它的工作原理。这并不完美。

但是所有的操作(我登录的)都是按顺序排列的,这个threadid描述了哪些操作符是在哪个ThreadId中。

+0

它的简单而干净的解决方案,但它需要添加一些过滤和订购工具。很多与id混合在一起,无法进行额外的文本处理。我正在考虑将此变体保留为:) – Mitklantekutli

+0

您想创建一个不错的查看器来记录文件吗?这是其他层,它是很多工具来做到这一点。 –

+0

我的问题是关于避免它。 – Mitklantekutli