21

REST サービスに Azure で Owin を使用しており、Application Insights に直接報告する必要があります。例外とリクエストをログに記録したいと考えています。現在、これがあります:

using AppFunc = Func<IDictionary<string, object>, Task>;
public class InsightsReportMiddleware
{

    readonly AppFunc next;
    readonly TelemetryClient telemetryClient;

    public InsightsReportMiddleware(AppFunc next, TelemetryClient telemetryClient)
    {
        if (next == null)
        {
            throw new ArgumentNullException("next");
        }

        this.telemetryClient = telemetryClient;
        this.next = next;
    }

    public async Task Invoke(IDictionary<string, object> environment)
    {
        var sw = new Stopwatch();
        sw.Start();

        await next(environment);
        sw.Stop();

        var ctx = new OwinContext(environment);
        var rt = new RequestTelemetry(
            name: ctx.Request.Path.ToString(),
            timestamp: DateTimeOffset.Now,
            duration: sw.Elapsed,
            responseCode: ctx.Response.StatusCode.ToString(),
            success: 200 == ctx.Response.StatusCode
            );

        rt.Url = ctx.Request.Uri;
        rt.HttpMethod = ctx.Request.Method;
        telemetryClient.TrackRequest(rt);
    }
}


public class InsightsExceptionLogger : ExceptionLogger
{
    readonly TelemetryClient telemetryClient;

    public InsightsExceptionLogger(TelemetryClient telemetryClient)
    {
        this.telemetryClient = telemetryClient;            
    }

    public override Task LogAsync(ExceptionLoggerContext context, System.Threading.CancellationToken cancellationToken)
    {
        telemetryClient.TrackException(context.Exception);
        return Task.FromResult<object>(null);
    }

    public override void Log(ExceptionLoggerContext context)
    {
        telemetryClient.TrackException(context.Exception);
    }
}

それらは次のようにアプリケーションに登録されます。

static void ConfigureInsights(IAppBuilder app, HttpConfiguration config)
{
    var rtClient = new TelemetryClient();
    app.Use<InsightsReportMiddleware>(rtClient);
    config.Services.Add(typeof (IExceptionLogger), new InsightsExceptionLogger(rtClient));
}

例外とリクエストが接続されていないことを除いて、これは機能します。どちらもログに記録されますが、失敗したリクエストをクリックすると、「関連する例外が見つかりませんでした」と表示されます。逆に、例外プロパティを開くと、「この例外の影響を受けたリクエスト: 0」を読み取ることができます。それを行う適切な方法は何ですか?

4

4 に答える 4

11

Application Insights は、 と を比較して、例外と要求をリンクしExceptionTelemetry.Context.Operation.IdますRequestTelemetry.Id

OWIN のコード サンプルはありませんが、Application Insights SDK のASP.NET 5 パッケージには、例外と要求を追跡するための同様のミドルウェア コンポーネントがあります。この情報を使用して、OWIN のソリューションを構築していただければ幸いです。

実際のリクエスト処理を実行する次のミドルウェア コンポーネントを呼び出す前に、インスタンスを作成RequestTelemetryしてリクエスト処理環境に格納します。ASP.NET 5 では、RequestTelemetry を要求スコープ サービスとして登録します。OWIN では、ミドルウェア コンポーネントがそれを作成し、environment辞書に格納すると思います。

環境から抽出されたを設定するOperationIdTelemetryInitializerITelemetryInitializerというもあります。この初期化子は、アプリケーションでインスタンスを作成するために使用される に追加する必要があります。がデフォルトで使用されます。ITelemetry.Context.Operation.IdRequestTelemetry.IdTelemetryConfigurationTelemetryClientTelemetryConfiguration.Active

于 2015-06-03T20:13:00.763 に答える
11

私がやったこと:

using AppFunc = Func<IDictionary<string, object>, Task>;
public class InsightsReportMiddleware
{
    readonly AppFunc next;
    readonly TelemetryClient telemetryClient;

    public InsightsReportMiddleware(AppFunc next, TelemetryClient telemetryClient)
    {
        if (next == null)
        {
            throw new ArgumentNullException("next");
        }

        this.telemetryClient = telemetryClient;
        this.next = next;
    }

    public async Task Invoke(IDictionary<string, object> environment)
    {
        var ctx = new OwinContext(environment);
        var rt = new RequestTelemetry()
        {
            Url = ctx.Request.Uri,
            HttpMethod = ctx.Request.Method,
            Name = ctx.Request.Path.ToString(),
            Timestamp = DateTimeOffset.Now
        };
        environment.Add("requestTelemetry", rt);

        var sw = new Stopwatch();
        sw.Start();
        await next(environment);
        sw.Stop();

        rt.ResponseCode = ctx.Response.StatusCode.ToString();
        rt.Success = ctx.Response.StatusCode < 400;
        rt.Duration = sw.Elapsed;
        telemetryClient.TrackRequest(rt);
    }
}

public class InsightsExceptionLogger : ExceptionLogger
{
    readonly TelemetryClient telemetryClient;

    public InsightsExceptionLogger(TelemetryClient telemetryClient)
    {
        this.telemetryClient = telemetryClient;            
    }

    public override Task LogAsync(ExceptionLoggerContext context, System.Threading.CancellationToken cancellationToken)
    {
        var owinContext = context.Request.GetOwinEnvironment();
        ExceptionTelemetry exceptionTelemetry = null;
        if (owinContext != null)
        {
            object obj;
            if (owinContext.TryGetValue("requestTelemetry", out obj))
            {
                var requestTelemetry = obj as RequestTelemetry;
                exceptionTelemetry = new ExceptionTelemetry(context.Exception)
                {
                    Timestamp = DateTimeOffset.Now
                };
                exceptionTelemetry.Context.Operation.Id = requestTelemetry.Id;
            }
        }

        if (exceptionTelemetry != null)
        {
            telemetryClient.TrackException(exceptionTelemetry);
        }
        else
        {
            telemetryClient.TrackException(context.Exception);                
        }

        return Task.FromResult<object>(null);
    }

    public override void Log(ExceptionLoggerContext context)
    {
        telemetryClient.TrackException(context.Exception);
    }
}
于 2015-06-12T10:38:25.630 に答える
1

私の現在のクライアントについては、まだ OWIN を行っていません。

DelegatingHandler現在のリクエストをスレッドのSynchronizationContextビアに貼り付けCallContext.LogicalSetData、リクエストが完了した後に削除するWebAPIを登録しました。

Application Insights のものを後付けする必要があった私の既存のログ システムでは、スレッドから要求を取得し、フレームワークによって要求プロパティに配置される をCallContext.LogicalSetData取得するように設定します。インスタンス。HttpContextHttpContext.ItemsRequestTelemetry

最終的には、サービスを新規作成している IoC コンテナーから要求やアクションなどにアクセスできないため、これがすべて必要になります。

最終的には、これの一部を書き直して、OperationContextまたはスタイル オブジェクトの作成とスタックへのフローを改善し、ハンドラーと面白いビジネスInstrumentationContextを取り除くことができます。CallContext

于 2015-11-11T17:51:06.643 に答える