我们需要在特定于用户的基础上分离REST Web服务生成的日志,并最终将这些日志导入到Datadogs.com之类的聚合框架中。
有几种方法可以解决这个问题,我很想在选择一种方法之前获得反馈。
基本知识如下:
取决于舞台
对于开发,请使用NLOG File Logger,以便开发人员可以简单地“尾随”日志文件。将nlog文件名目标中的变量用作
<target filename="/path/file-${var:userid}.log"/>.
或在nlog目标中将其用作:
layout="${var:userid}-${OtherLayout}
”,并让开发人员执行tail -f masterFile.log | grep USERID.
在生产中切换为使用nlog JsonLayout,因此诸如DataDog的系统可以读取Time,Threadid,Userid和消息数据。使用JsonFormat并指定用户标识属性。我看到JsonFormat支持MappedDiagnosticsLogicalContext,但是我更喜欢$ {var:xxx}格式的简单性来指定值。
问题:
我过去曾经使用过MappedDiagnosticContext,然后在目标文件名中指定了它。我只是尝试使用$ {var}方法,但似乎没有用??
关注点:
我喜欢使用文件名目标方法进行开发。它应该适合10-100个用户,但不能扩展到1000个用户。显然,对于1000个用户,我们将需要在写入每一行后关闭日志文件,因为我们不想保持1000个文件处于打开状态。
主要关注的是线程。每个Web服务可能被不同的用户多次调用,并且所有方法都需要Nlog MappedDiagnosticContext或$ {var}功能才是线程安全的。是吗?有什么要考虑的问题吗?
最终,我们想在系统中引入一些结构化日志记录,但是大多数代码库都是使用标准日志记录技术构建的。如果要在结构化日志中记录的对象包括userid,则可以避免这种复杂性,但这将需要大量工作来重写结构化日志。
很明显,有很多事情要考虑,我知道我不是第一个对此进行思考的人。
您的输入将不胜感激。
答案 0 :(得分:1)
仅在需要时将NLog.MappedDiagnosticsLogicalContext.Set("userid", "someValue")
与${mdlc:item=userid}
一起使用。另请参见http://github.com/NLog/NLog/wiki/MDLC-Layout-Renderer
MappedDiagnosticsLogicalContext
使用线程安全的CallContext
(在NetCore上为AsyncLocal
)。设置还将支持异步任务并遵循链接的任务,但是如果基于用户请求安排时间回调,则计时器回调将看不到用户ID。
您应该避免在运行时更改LogManager.Configuration.Variable
,它们对于所有并发请求都是全局的,并且可能在配置重装期间丢失(如果配置了自动重装)。