为何AsyncTaskTarget无法获取Scope属性,TargetWithContext却可以?
问题:AsyncTaskTarget无法获取ScopeContext属性,TargetWithContext可正常工作
我在实现日志目标时遇到一个问题:继承TargetWithContext的目标类能正常获取Scope属性,但继承AsyncTaskTarget时,调用GetScopeContextProperties返回NULL。
使用版本:NLog.Web.AspNetCore 5.2.3(依赖NLog 5.1.3和Microsoft.Extensions.Logging 7.0.0)
添加Scope的代码:
using (_logger.BeginScope(new[] { KeyValuePair.Create("example-key", "example-value") })) { _logger.LogInformation("test"); }
正常工作的TargetWithContext实现
public class ExampleTarget : TargetWithContext { public ExampleTarget() { this.IncludeScopeProperties = true; } protected override void Write(LogEventInfo logEvent) { // 能正常获取值 var scopeValues = GetScopeContextProperties(logEvent); } }
不生效的AsyncTaskTarget实现
public class ExampleTarget : AsyncTaskTarget { public ExampleTarget() { this.IncludeScopeProperties = true; } protected override async Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken cancellationToken) { // 返回NULL var scopeValues = GetScopeContextProperties(logEvent); } }
原因及解决方法
原因
AsyncTaskTarget虽继承自TargetWithContext,但异步执行流程中不会自动触发Scope属性的收集逻辑;而同步的TargetWithContext在执行Write方法前,已完成Scope属性的填充。
解决方法
在WriteAsyncTask中手动调用PopulateScopeContextProperties,确保Scope属性被填充到logEvent后,再调用GetScopeContextProperties即可获取到值。
修改后的AsyncTaskTarget实现:
public class ExampleTarget : AsyncTaskTarget { public ExampleTarget() { this.IncludeScopeProperties = true; } protected override async Task WriteAsyncTask(LogEventInfo logEvent, CancellationToken cancellationToken) { // 手动填充Scope属性 PopulateScopeContextProperties(logEvent); // 现在可正常获取Scope值 var scopeValues = GetScopeContextProperties(logEvent); // 后续异步业务逻辑 await Task.CompletedTask; } }
如果你的AsyncTaskTarget需要批量处理日志(重写WriteAsyncTasks方法),需在处理每个日志事件前调用PopulateScopeContextProperties,保证所有日志事件的Scope属性都被正确填充。
内容的提问来源于stack exchange,提问作者marsze
相关产品推荐
相关产品推荐

