繁体   English   中英

Serilog 中环境 LogContext 的线程安全

[英]Thread safety of the ambient LogContext in Serilog

根据这篇文章,您可以将请求 ID 附加到 Serilog 中的环境上下文( LogContext ),如下所示:

using (LogContext.PushProperty("RequestId", Request.Id))
{
    // Process request; all logged events will carry `RequestId`
    Log.Information("Adding {Item} to cart {CartId}", item, cart.Id);
}

这很好,而且似乎正在工作。 我有两个需要这个的场景:

  • 将相关 ID 添加到对 API 的每个请求的日志中。
  • 为队列的每条消息读取添加一个相关 ID。

让我感到困惑的是,如果多个请求同时命中 API,或者我们同时处理多个消息,会发生什么。 由于LogContext是 static class,我是否可以不小心用来自另一个线程的值而不是最初设置该属性的值覆盖LogContext中的RequestId属性?

假设线程 1 将RequestId设置为1 在完成之前,线程 2 将RequestId设置为2 ,因为我们收到了另一个请求。 线程 1 现在是否会在记录时使用2作为RequestId的值? 我猜它不会,但有人可以解释为什么吗? 根据this ,将与现有属性同名的属性推送到堆栈上会覆盖它:

将属性推送到上下文将覆盖任何具有相同名称的现有属性,直到从 PushProperty() 返回的 object 被释放,如示例中的属性 A 所示。

Serilog 是否每个从LogContext.PushProperty(...)方法返回的句柄都有一个堆栈,还是什么? 有什么办法可以覆盖RequestId ,也许没有再次调用LogContext.PushProperty("RequestId", Request.Id)

LogContext 通过 AsyncLocal/ThreadStatic 是线程安全的 尽管通过 static class 访问每个线程都有自己的 LogContext。 请求不共享相同的 LogContext。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM