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

时间:2017-08-17 07:37:57

标签: .net owin azure-application-insights

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

主要是,我想提取POST正文。

我的问题与this other answer

有关

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

我无法做到这一点......就像在OWIN环境中一样。

有什么想法吗?

由于

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

我只想延长baywet的答案。

如果可以的话,我建议使用现有的nuget package来扩展Application Insights和OWIN。在这种情况下,您至少需要.NET Framework 4.6.1

否则你可以使用" my"解。我刚刚将两个答案混合在一起:

我需要的是记录异常和请求。这就是我所做的......(这里我写了一些基本的东西,让你写一个有效的解决方案)。

我创建了两个不同的对象跟踪器:TrackerExceptionTrackerRequest。两者都实现了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是一个只启用或不启用跟踪器的类......在此实现:

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包。