You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Logger.BeginScope在.NET Core 2.0中与Application Insights正常工作?

解决.NET Core 2.0中Application Insights不捕获ILogger BeginScope内容的问题

你遇到的情况是对的——.NET Core 2.0对应的Application Insights ILogger默认实现确实不会自动将BeginScope中的内容附加到跟踪日志里,不是你配置错了,而是需要额外的设置或者SDK版本升级来实现这个功能。下面给你两种可行的解决办法:


方法1:自定义TelemetryInitializer提取Scope信息

Application Insights允许通过ITelemetryInitializer来修改或补充遥测数据,我们可以用它来把Scope的内容添加到跟踪日志的自定义属性中。

步骤1:实现自定义TelemetryInitializer

如果是Web应用,可以借助IHttpContextAccessor来传递Scope信息;如果是非Web场景,用AsyncLocal来存储当前Scope:

Web场景示例:

public class ScopeTelemetryInitializer : ITelemetryInitializer
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ScopeTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }

    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is TraceTelemetry traceTelemetry)
        {
            // 从HttpContext中读取预先存储的Scope内容
            if (_httpContextAccessor.HttpContext?.Items.TryGetValue("CurrentScope", out var scopeValue) == true)
            {
                traceTelemetry.Properties["Scope"] = scopeValue.ToString();
            }
        }
    }
}

非Web场景(用AsyncLocal):

先创建一个静态类存储Scope:

public static class CurrentScopeHolder
{
    private static readonly AsyncLocal<string> _currentScope = new AsyncLocal<string>();
    public static string Value
    {
        get => _currentScope.Value;
        set => _currentScope.Value = value;
    }
}

然后修改TelemetryInitializer:

public class ScopeTelemetryInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        if (telemetry is TraceTelemetry traceTelemetry && !string.IsNullOrEmpty(CurrentScopeHolder.Value))
        {
            traceTelemetry.Properties["Scope"] = CurrentScopeHolder.Value;
        }
    }
}

步骤2:注册TelemetryInitializer

在Startup.cs的ConfigureServices方法中注册这个初始化器:

public void ConfigureServices(IServiceCollection services)
{
    // 注册Application Insights
    services.AddApplicationInsightsTelemetry();
    // 注册自定义初始化器
    services.AddSingleton<ITelemetryInitializer, ScopeTelemetryInitializer>();
    // 别忘了注册IHttpContextAccessor(Web场景需要)
    services.AddHttpContextAccessor();
    
    // 其他服务配置...
}

步骤3:在BeginScope时存储Scope内容

使用Scope的时候,把内容存入对应的存储位置:

// Web场景
using (_logger.BeginScope("Some really useful information"))
{
    HttpContext.Items["CurrentScope"] = "Some really useful information";
    _logger.LogError("Oh no.");
}

// 非Web场景
using (_logger.BeginScope("Some really useful information"))
{
    CurrentScopeHolder.Value = "Some really useful information";
    _logger.LogError("Oh no.");
}

这样,你在Application Insights的跟踪日志里就能看到名为Scope的自定义属性,值就是你传入的内容了。


方法2:升级Application Insights SDK版本

更简单的方式是升级Microsoft.ApplicationInsights.AspNetCore包到2.1.0及以上版本——这个版本开始,SDK默认支持将BeginScope的内容自动附加到跟踪日志的自定义属性中,无需额外代码。

因为你用的是.NET Core 2.0,2.1.0版本的SDK是兼容的,直接在NuGet包管理器中升级即可。升级后:

  • 如果你的Scope是字符串(比如BeginScope("xxx")),会自动添加一个名为Scope的自定义属性
  • 如果你的Scope是字典类型(比如BeginScope(new Dictionary<string, object> { { "UserId", "123" } })),字典里的每个键值对都会作为单独的自定义属性出现在跟踪日志里

两种方法都能解决你的问题,推荐优先尝试升级SDK,这样最省心;如果因为项目限制无法升级,再用自定义TelemetryInitializer的方式。

内容的提问来源于stack exchange,提问作者jsk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 03:14:08