13

Chúng tôi đang sử dụng Owin trên Azure cho dịch vụ REST và phải báo cáo trực tiếp cho Thông tin chi tiết về ứng dụng. Chúng tôi muốn đăng nhập ngoại lệ và yêu cầu. Ngay bây giờ chúng tôi có điều này:Cách liên kết ngoại lệ với các yêu cầu trong Thông tin chi tiết về ứng dụng trên Azure?

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); 
    } 
} 

Họ đã được đăng ký để ứng dụng của chúng tôi như sau:

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

này hoạt động, trừ trường hợp ngoại lệ và yêu cầu are not connected. Cả hai đều được ghi lại, nhưng khi nhấp vào một yêu cầu thất bại, nó nói "Không tìm thấy ngoại lệ nào liên quan". Ngược lại, khi mở một thuộc tính ngoại lệ, chúng ta có thể đọc "Yêu cầu bị ảnh hưởng bởi ngoại lệ này: 0". Cách thích hợp để làm điều đó là gì?

Trả lời

7

Thông tin chi tiết về ứng dụng liên kết các ngoại lệ và yêu cầu bằng cách so sánh ExceptionTelemetry.Context.Operation.IdRequestTelemetry.Id.

Tôi không có mẫu mã cho OWIN, tuy nhiên, ASP.NET 5 package SDK ứng dụng thông tin chi tiết có các thành phần phần mềm trung gian tương tự để theo dõi ngoại lệ và yêu cầu. Tôi hy vọng bạn có thể sử dụng thông tin này để xây dựng một giải pháp cho OWIN.

Chúng tôi tạo một ví dụ RequestTelemetry và lưu trữ trong môi trường xử lý yêu cầu trước khi gọi thành phần trung gian tiếp theo thực hiện xử lý yêu cầu thực tế. Trong ASP.NET 5, chúng tôi đăng ký RequestTelemetry như một dịch vụ theo yêu cầu. Với OWIN, tôi tưởng tượng thành phần middleware của bạn sẽ tạo ra nó và lưu trữ nó trong từ điển environment.

Chúng tôi cũng có một số ITelemetryInitializer, được gọi là OperationIdTelemetryInitializer, đặt ITelemetry.Context.Operation.Id với RequestTelemetry.Id được trích xuất từ ​​môi trường. Trình khởi tạo này cần phải được thêm vào số TelemetryConfiguration được sử dụng để tạo các trường hợp TelemetryClient trong ứng dụng của bạn. TelemetryConfiguration.Active được sử dụng theo mặc định.

+0

"OperationIdTelemetryInitializer, đặt ITelemetry.Context.Operation.Id bằng RequestTelemetry.Id được trích xuất từ ​​môi trường" bạn có ý tưởng về cách thực hiện điều đó trong OWIN không?Việc triển khai AspNet cuối cùng thực hiện 'httpContextAccessor.HttpContext.RequestServices.GetService ()'. Làm thế nào nó có thể truy cập một bối cảnh địa phương, phạm vi từ một singleton toàn cầu? Làm thế nào điều này có thể hỗ trợ yêu cầu đồng bộ đồng thời? – trethaller

7

gì tôi đã kết thúc-up thực hiện:

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); 
    } 
} 
1

Đối với khách hàng hiện tại của tôi, chúng tôi chưa OWIN-ed lên.

Tôi đã đăng ký DelegatingHandler bằng WebAPI gắn yêu cầu hiện tại vào số SynchronizationContext của chủ đề qua CallContext.LogicalSetData và xóa sau khi yêu cầu hoàn tất.

Trong hệ thống đăng nhập hiện tại của tôi, phải được trang bị retro với công cụ Thông tin chi tiết về ứng dụng, sau đó tôi lấy yêu cầu từ chuỗi qua CallContext.LogicalSetData và đặt về số HttpContext được đặt vào thuộc tính yêu cầu theo khuôn khổ, sau đó từ HttpContext.Items, tôi nhận được phiên bản RequestTelemetry.

Cuối cùng, điều này là tất cả cần thiết vì tôi không thể truy cập vào yêu cầu hoặc hành động hoặc bất kỳ thứ gì từ container IoC đang khởi tạo các dịch vụ.

Cuối cùng, chúng tôi có thể viết lại một số điều này để cho phép tạo và cải thiện đối tượng kiểu OperationContext hoặc InstrumentationContext xuống ngăn xếp và loại bỏ trình xử lý và CallContext hoạt động vui nhộn.

Các vấn đề liên quan