【发布时间】:2019-01-02 14:04:59
【问题描述】:
我们需要在特定用户的基础上分离 REST Web 服务生成的日志,并最终将这些日志导入到 Datadogs.com 等聚合框架中。
有几种方法可以解决这个问题,我有兴趣在选择方法之前获得反馈。
基本情况如下:
- 使用 UserID 作为参数调用 Rest 服务。
- 设置nlog LogManager.Configuration.Variable["userid"] = userid,或者使用MappedDiagnosticContext。
- 正常写入日志,直到 REST 调用完成。
视阶段而定
对于开发,使用 NLOG 文件记录器,因此开发人员可以简单地“跟踪”日志文件。使用 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} 功能是线程安全的。是吗?有什么需要考虑的问题吗?
最终我们想在系统中引入一些结构化日志记录,但大部分代码库都是使用标准日志记录技术构建的。如果在结构化日志记录中记录的对象包括用户 ID,那么可以避免大部分复杂性,但这需要为结构化日志记录重写大量工作。
显然,有很多事情要考虑,我知道我不是第一个思考这个问题的人。
您的意见将不胜感激。
【问题讨论】:
-
只需在需要的地方使用
NLog.MappedDiagnosticsLogicalContext.Set("userid", "someValue")和${mdlc:item=userid}。另见github.com/NLog/NLog/wiki/MDLC-Layout-Renderer -
您应该避免在运行时更改
LogManager.Configuration.Variable,它们对于所有并发请求都是全局的,并且可能会在配置重载期间丢失(如果配置了自动重载)。 -
我做到了,它有效.. 问题:你知道这是否是线程安全的吗?
-
是的
MappedDiagnosticsLogicalContext是线程安全的,我现在已经在我的回答中解释了。