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

为Nancy应用的Application Insights遥测添加请求头的方案问询

在Nancy应用中为Application Insights请求事件添加请求头的解决方案

我太懂你这个痛点了——网上搜的Application Insights加请求头的方案全是依赖HttpContext的,可Nancy根本不吃那一套,连个静态的HttpContext.Current都没有,之前试的方案全卡壳对吧?别愁,我给你一套亲测可行的流程,核心就是用**异步本地存储(AsyncLocal)**把Nancy的请求上下文传递给TelemetryInitializer:


1. 先做个上下文“中转站”:用AsyncLocal存NancyContext

Nancy的请求上下文是和当前请求绑定的,没有静态访问入口,那我们就自己造一个能在异步流程里稳定传递的存储容器:

public static class NancyContextHolder
{
    // AsyncLocal能保证在异步调用链里上下文不串线
    private static readonly AsyncLocal<NancyContext> _currentContext = new AsyncLocal<NancyContext>();

    public static NancyContext CurrentContext
    {
        get => _currentContext.Value;
        set => _currentContext.Value = value;
    }
}

2. 绑定Nancy请求生命周期:把上下文存进中转站

通过Nancy的IRequestStartup接口,在每个请求启动时把当前的NancyContext塞进我们的Holder里,请求结束后记得清理,避免内存泄漏:

public class NancyContextSetup : IRequestStartup
{
    public void Initialize(IPipelines pipelines, NancyContext context)
    {
        // 请求开始时存上下文
        NancyContextHolder.CurrentContext = context;
        
        // 请求结束后清空,防止线程复用导致上下文混乱
        pipelines.AfterRequest.AddItemToEndOfPipeline(_ => NancyContextHolder.CurrentContext = null);
    }
}

然后要在Nancy的Bootstrapper里注册这个启动类,让Nancy每次处理请求都执行它:

public class CustomNancyBootstrapper : DefaultNancyBootstrapper
{
    protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
    {
        base.ApplicationStartup(container, pipelines);
        // 把我们的上下文注册逻辑交给Nancy容器管理
        container.Register<IRequestStartup, NancyContextSetup>();
    }
}

3. 写自定义TelemetryInitializer:从中转站拿头,塞进AI请求事件

现在我们能在任意地方拿到当前请求的NancyContext了,接下来写个ITelemetryInitializer,把请求头加到Application Insights的请求遥测属性里:

public class NancyRequestHeadersTelemetryInitializer : ITelemetryInitializer
{
    public void Initialize(ITelemetry telemetry)
    {
        // 只处理请求遥测,并且确保上下文存在
        if (telemetry is RequestTelemetry requestTelemetry && NancyContextHolder.CurrentContext != null)
        {
            var requestHeaders = NancyContextHolder.CurrentContext.Request.Headers;
            
            foreach (var header in requestHeaders)
            {
                // 重点!过滤敏感头,别把Authorization、Cookie这种信息存进去
                if (header.Key.Equals("Authorization", StringComparison.OrdinalIgnoreCase) || 
                    header.Key.Equals("Cookie", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                // 一个头可能有多个值,用逗号拼接起来
                var headerValue = string.Join(", ", header.Value);
                // 避免重复添加属性
                if (!requestTelemetry.Properties.ContainsKey(header.Key))
                {
                    requestTelemetry.Properties.Add(header.Key, headerValue);
                }
            }
        }
    }
}

4. 注册初始化器到Application Insights

最后一步,在应用启动的时候把这个自定义的初始化器加到AI的配置里,比如在宿主启动的地方:

// 初始化AI配置,添加我们的自定义初始化器
var telemetryConfig = TelemetryConfiguration.CreateDefault();
telemetryConfig.TelemetryInitializers.Add(new NancyRequestHeadersTelemetryInitializer());

// 把配置传给TelemetryClient,或者让依赖注入容器管理它
var telemetryClient = new TelemetryClient(telemetryConfig);

几个要注意的坑

  • 敏感信息过滤:一定要像上面那样排除掉敏感请求头,不然会泄露用户隐私或者安全信息,也可以根据自己的业务需求加更多过滤规则。
  • 上下文清理:AfterRequest里的清空操作不能少,不然线程池复用的时候可能会把上一个请求的上下文带进来,导致数据错乱。
  • 测试验证:部署后去Application Insights的“请求”事件里,查看每个请求的“自定义属性”,就能看到你加的请求头了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:52:55