使用 Hangfire 过滤器记录相关 ID
Log correlation id using Hangfire Filter
我正在尝试使用 Hangfire Filter and ILogger.BeginScope 来记录关联 ID。要求是每个作业执行都有自己的相关 ID,以便在发生某些事情时更容易将同一作业执行的日志分组在一起。
我的方法是在IServerFilter.OnPerforming
方法中,我首先创建一个GUID,然后使用下面的代码开始作用域
logger.BeginScope(new FormattedDictionary<string, object>
{
["CorrelationId"] = correlationId
})
方法 IServerFilter.OnPerforming
中的后续日志语句将附加关联 ID。但不幸的是,在作业执行期间,日志语句将不具有关联 ID 范围。使用构造函数解析作业 class 的 ILogger
实例。方法 IServerFilter.OnPerforming
的 ILogger
实例使用 IServiceProvider.GetRequiredService
方法
解析
我想知道为什么会这样?我们如何解决这个问题?只要有效,我愿意接受其他实现日志记录相关 ID 的方法。
终于想通了。原因是当由本地 ILogger
实例创建的 IServerFilter.OnPerforming
中的本地 IDisposable
超出范围时,由于没有任何内容再次引用它,一段时间后,GC 将收集它,因此本地创建的范围将丢失。解决方案很简单,在过滤器上使用 AsyncLocal<ILogger>
实例来保存对创建的范围的引用,并且仅在作业完成后处理它
我正在尝试使用 Hangfire Filter and ILogger.BeginScope 来记录关联 ID。要求是每个作业执行都有自己的相关 ID,以便在发生某些事情时更容易将同一作业执行的日志分组在一起。
我的方法是在IServerFilter.OnPerforming
方法中,我首先创建一个GUID,然后使用下面的代码开始作用域
logger.BeginScope(new FormattedDictionary<string, object>
{
["CorrelationId"] = correlationId
})
方法 IServerFilter.OnPerforming
中的后续日志语句将附加关联 ID。但不幸的是,在作业执行期间,日志语句将不具有关联 ID 范围。使用构造函数解析作业 class 的 ILogger
实例。方法 IServerFilter.OnPerforming
的 ILogger
实例使用 IServiceProvider.GetRequiredService
方法
我想知道为什么会这样?我们如何解决这个问题?只要有效,我愿意接受其他实现日志记录相关 ID 的方法。
终于想通了。原因是当由本地 ILogger
实例创建的 IServerFilter.OnPerforming
中的本地 IDisposable
超出范围时,由于没有任何内容再次引用它,一段时间后,GC 将收集它,因此本地创建的范围将丢失。解决方案很简单,在过滤器上使用 AsyncLocal<ILogger>
实例来保存对创建的范围的引用,并且仅在作业完成后处理它