如何在 AppInsights 遥测初始化程序中访问 OWIN 请求?

How do i access the OWIN Request in an AppInsights Telemetry Initializer?

我正在尝试在我的自定义 AppInsights 遥测初始化程序中访问 HTTP 请求。

主要是想提取POST正文。

我的问题涉及

但是,答案表明使用HttpContext.Current.Request.InputStream

我不能这样做...因为我在 OWIN 环境中。

有什么想法吗?

谢谢

OWIN 引入了中间件的概念(后来由 asp.net 核心扩展),要求您分层构建应用程序。
它提高可维护性、性能以及保持高水平的关注点分离的主要原因之一。
在此过程中,他们删除了大部分静态上下文变量(如 httpContext.Current),OWIN 基础结构将作为 OwinContext 将等效信息传递给您的中间件。
也就是说,如果您使用 Application Insights,则不必从头开始编写中间件,一个出色的 nuget package 可以帮助您更快地实现目标。 最后,由于实现方式的原因,请求的主体只能使用一次(至少是安全的)see related github issue

我只想扩展 baywet 的答案。

如果可以,我建议使用现有的nuget package to extend Application Insights with OWIN. In that case you need at least .NET Framework 4.6.1

否则您可以使用 "my" 解决方案。我刚刚混合了这两个答案:

  • How to log response body in a OWIN Middleware

我需要的是记录异常和请求。这就是我所做的..(在这里我写了必要的东西让你写出一个可行的解决方案)。

我创建了两个不同的对象跟踪器:TrackerException 和一个 TrackerRequest。两者都实现了 Proxy Pattern。通过这种方式,我不必明显关心我决定跟踪的内容。我只是让你看到一个跟踪器的更简单的实现:

public class TrackerException : ITracker
{
    private readonly TelemetryClient _telemetryClient;
    public TrackerException(TelemetryClient telemetryClient)
    {
        this._telemetryClient = telemetryClient;
    }

    public void Track(ITelemetryObject telemetry)
    {
        if (telemetry is TelemetryExceptionObject)
        {
            Exception ex = ((TelemetryExceptionObject)telemetry).Exception;
            this._telemetryClient.TrackException(ex);
        }
    }
}

我在自定义 Owin 中间件中使用跟踪器:

public class ApplicationInsightsMiddleware : OwinMiddleware
{
    private TrackingOptions _trackingOptions;

    public ApplicationInsightsMiddleware(OwinMiddleware next) 
        : base(next)
    { }

    public ApplicationInsightsMiddleware(OwinMiddleware next, TrackingOptions trackingOptions) 
        : base(next)
    {
        this._trackingOptions = trackingOptions;
    }

    public override async Task Invoke(IOwinContext context)
    {
        var client = new TelemetryClient();
        this._trackingOptions.TelemetryClient = client;

        // Start Time Tracking
        var sw = new Stopwatch();
        var startTime = DateTimeOffset.Now;
        sw.Start();

        this._trackingOptions.TrackRequest.ReadRequestBody(context.Request);

        try
        {
            await Next.Invoke(context); 
        }
        catch (Exception ex)
        {
            ITelemetryObject exception = new TelemetryExceptionObject(ex);
            this._trackingOptions.TrackException.Track(exception);

            throw ex;
        }

        RequestTelemetry requestTelemetry = this._trackingOptions.TrackRequest.CreateTelemetryRequest(context.Request, context.Response, startTime, sw.Elapsed);
        ITelemetryObject request = new TelemetryRequestObject(requestTelemetry);
        this._trackingOptions.TrackRequest.Track(request);

        sw.Stop();
    }
}

TrackingOptions 是一个 class,它只是启用或不启用跟踪器...这里是它的实现:

public class TrackingOptions
{
    //Here I initialize all my trackers

    private ProxyTrackerException _trackException;
    internal ProxyTrackerException TrackException { get { return _trackException; } }

    private TelemetryClient _telemetryClient;
    internal TelemetryClient TelemetryClient
    {
        get { return _telemetryClient; }
        set { _telemetryClient = value; }
    }

    public TrackingOptions(bool enableTrackingRequest, bool enableTrackingException)
    {
        this.InitializeExceptionTracker(enableTrackingException);
        //...
    }

    private void InitializeExceptionTracker(bool enableTrackingException)
    {
        this._trackException = new ProxyTrackerException(enableTrackingException, this._telemetryClient);
    }
}

最后我写了一个Owin的扩展方法

public static void UseApplicationInsights(this IAppBuilder app, TrackingOptions options)
{
    app.Use(typeof(ApplicationInsightsMiddleware), options);
}

在我的项目启动时,我添加了我的新中间件:

app.UseApplicationInsights(
    new TrackingOptions(enableTrackingRequest: true, enableTrackingException: true)
);

但是,这对我来说是一个临时解决方案...我会尽快更新我的框架并安装现有的 nuget 包。