C# 将请求头添加到Application Insights telemetry for Nancy应用程序
我想在ApplicationInsights中的请求事件中包含标题,并找到了以下文章,其中包含了一个针对具有HttpContext的应用程序的解决方案。我正在使用一个Nancy应用程序,其中请求头存储在NancyContext中。问题是Nancy并没有提供像HttpContext.Current这样的静态访问器,所以我想知道如何解决这个问题 我做了两次尝试都没有成功。第一个是构建一个ITelemetryInitializer,如下面的链接所述,但是我无法访问NancyContext 我的第二次尝试是将NancyModule传递给一个静态函数,该函数将请求头添加到ITelemetryContext中,但是我无法获得当前的ITelemetryContextC# 将请求头添加到Application Insights telemetry for Nancy应用程序,c#,asp.net-core,nancy,azure-application-insights,telemetry,C#,Asp.net Core,Nancy,Azure Application Insights,Telemetry,我想在ApplicationInsights中的请求事件中包含标题,并找到了以下文章,其中包含了一个针对具有HttpContext的应用程序的解决方案。我正在使用一个Nancy应用程序,其中请求头存储在NancyContext中。问题是Nancy并没有提供像HttpContext.Current这样的静态访问器,所以我想知道如何解决这个问题 我做了两次尝试都没有成功。第一个是构建一个ITelemetryInitializer,如下面的链接所述,但是我无法访问NancyContext 我的第二次
还有其他人遇到并解决了这个问题吗?您的第二种方法应该可以工作,如果有,您可以使用现有的扩展方法来获取当前的请求遥测 方法是方法:
httpcontextension.GetRequestTelemetry
()
这将返回给定HttpContext的当前请求遥测,因此您应该能够:
var requestTelemetry = HttpContext.Current?.GetRequestTelemetry();
// add whatever you need to the request telemetry?
从Nancy模块内部?您的第二种方法应该可以工作,并且您可以使用现有的扩展方法来获取当前的请求遥测(如果有) 方法是方法:
httpcontextension.GetRequestTelemetry
()
这将返回给定HttpContext的当前请求遥测,因此您应该能够:
var requestTelemetry = HttpContext.Current?.GetRequestTelemetry();
// add whatever you need to the request telemetry?
从你的Nancy模块内部?我找到了一个解决方案,可能不是最漂亮的,但至少它似乎有效 我创建了一个静态可访问的
AsyncLocal
实例来保存每个线程的RequestTelemetry对象
public class RequestVariables
{
public static AsyncLocal<RequestTelemetry> RequestTelemetry = new AsyncLocal<RequestTelemetry>();
}
然后,我在Startup.Configure(…)
方法中注册了一个小型中间件,该方法获取RequestTelemetry
实例,该实例由ITelemetryInitializer
设置,并向其添加请求头
app.Use((context, next) =>
{
var requestTelemetry = RequestVariables.RequestTelemetry.Value;
if (requestTelemetry?.Context == null) return next();
foreach (var header in context.Request.Headers)
{
if (!requestTelemetry.Context.Properties.ContainsKey(header.Key))
requestTelemetry.Context.Properties.Add(header.Key, header.Value.First());
}
return next();
});
我找到了一个解决方案,可能不是最漂亮的,但至少它似乎有效 我创建了一个静态可访问的
AsyncLocal
实例来保存每个线程的RequestTelemetry对象
public class RequestVariables
{
public static AsyncLocal<RequestTelemetry> RequestTelemetry = new AsyncLocal<RequestTelemetry>();
}
然后,我在Startup.Configure(…)
方法中注册了一个小型中间件,该方法获取RequestTelemetry
实例,该实例由ITelemetryInitializer
设置,并向其添加请求头
app.Use((context, next) =>
{
var requestTelemetry = RequestVariables.RequestTelemetry.Value;
if (requestTelemetry?.Context == null) return next();
foreach (var header in context.Request.Headers)
{
if (!requestTelemetry.Context.Properties.ContainsKey(header.Key))
requestTelemetry.Context.Properties.Add(header.Key, header.Value.First());
}
return next();
});
实际上,.NET Framework有一个例子: 在.NET Core中,您只需使用IHttpContextAccessor而不是HttpContext来访问HttpContext。当前:
public class TelemetryHeadersInitializer : ITelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
public List<string> RequestHeaders { get; set; }
public List<string> ResponseHeaders { get; set; }
public TelemetryHeadersInitializer(IHttpContextAccessor httpContextAccessor)
{
RequestHeaders = new List<string> { "Referer" }; //whatever you need
ResponseHeaders = new List<string> { ... };
_httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
// Is this a TrackRequest() ?
if (requestTelemetry == null) return;
var context = _httpContextAccessor.HttpContext;
if (context == null) return;
foreach (var headerName in RequestHeaders)
{
var headers = context.Request.Headers[headerName];
if (headers.Any())
{
telemetry.Context.Properties.Add($"Request-{headerName}", string.Join(Environment.NewLine, headers));
}
}
foreach (var headerName in ResponseHeaders)
{
var headers = context.Response.Headers[headerName];
if (headers.Any())
{
telemetry.Context.Properties.Add($"Response-{headerName}", string.Join(Environment.NewLine, headers));
}
}
}
}
//Services.cs:
services.AddSingleton<ITelemetryInitializer, TelemetryHeadersInitializer>();
公共类遥测标头初始化器:ITelemetryInitializer
{
专用只读IHttpContextAccessor\u httpContextAccessor;
公共列表请求头{get;set;}
公共列表响应头{get;set;}
公共遥测磁头初始化器(IHttpContextAccessor httpContextAccessor)
{
RequestHeaders=新列表{“Referer”};//您需要什么
ResponseHeaders=新列表{…};
_httpContextAccessor=httpContextAccessor;
}
公共无效初始化(ITelemetry遥测)
{
var requestTelemetry=作为requestTelemetry的遥测;
//这是TrackRequest()吗?
if(requestTelemetry==null)返回;
var context=\u httpContextAccessor.HttpContext;
if(context==null)返回;
foreach(RequestHeaders中的var headerName)
{
var headers=context.Request.headers[headerName];
if(headers.Any())
{
remotery.Context.Properties.Add($“Request-{headerName}”,string.Join(Environment.NewLine,headers));
}
}
foreach(负责人中的var headerName)
{
var headers=context.Response.headers[headerName];
if(headers.Any())
{
remotery.Context.Properties.Add($“Response-{headerName}”,string.Join(Environment.NewLine,headers));
}
}
}
}
//服务中心:
services.AddSingleton();
同时检查:
实际上,.NET Framework有一个例子: 在.NET Core中,您只需使用IHttpContextAccessor而不是HttpContext来访问HttpContext。当前:
public class TelemetryHeadersInitializer : ITelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
public List<string> RequestHeaders { get; set; }
public List<string> ResponseHeaders { get; set; }
public TelemetryHeadersInitializer(IHttpContextAccessor httpContextAccessor)
{
RequestHeaders = new List<string> { "Referer" }; //whatever you need
ResponseHeaders = new List<string> { ... };
_httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
// Is this a TrackRequest() ?
if (requestTelemetry == null) return;
var context = _httpContextAccessor.HttpContext;
if (context == null) return;
foreach (var headerName in RequestHeaders)
{
var headers = context.Request.Headers[headerName];
if (headers.Any())
{
telemetry.Context.Properties.Add($"Request-{headerName}", string.Join(Environment.NewLine, headers));
}
}
foreach (var headerName in ResponseHeaders)
{
var headers = context.Response.Headers[headerName];
if (headers.Any())
{
telemetry.Context.Properties.Add($"Response-{headerName}", string.Join(Environment.NewLine, headers));
}
}
}
}
//Services.cs:
services.AddSingleton<ITelemetryInitializer, TelemetryHeadersInitializer>();
公共类遥测标头初始化器:ITelemetryInitializer
{
专用只读IHttpContextAccessor\u httpContextAccessor;
公共列表请求头{get;set;}
公共列表响应头{get;set;}
公共遥测磁头初始化器(IHttpContextAccessor httpContextAccessor)
{
RequestHeaders=新列表{“Referer”};//您需要什么
ResponseHeaders=新列表{…};
_httpContextAccessor=httpContextAccessor;
}
公共无效初始化(ITelemetry遥测)
{
var requestTelemetry=作为requestTelemetry的遥测;
//这是TrackRequest()吗?
if(requestTelemetry==null)返回;
var context=\u httpContextAccessor.HttpContext;
if(context==null)返回;
foreach(RequestHeaders中的var headerName)
{
var headers=context.Request.headers[headerName];
if(headers.Any())
{
remotery.Context.Properties.Add($“Request-{headerName}”,string.Join(Environment.NewLine,headers));
}
}
foreach(负责人中的var headerName)
{
var headers=context.Response.headers[headerName];
if(headers.Any())
{
remotery.Context.Properties.Add($“Response-{headerName}”,string.Join(Environment.NewLine,headers));
}
}
}
}
//服务中心:
services.AddSingleton();
同时检查:
未能通过这种方式获得请求遥测。可能是因为我的项目是AspNetCore,它使用的是
Microsoft.AspNe