异常的应用洞察和自定义属性

问题描述 投票:0回答:3

我有以下例外:

public class InvalidStatusCodeException : Exception
{
    public HttpStatusCode ReceivedStatusCode { get; set; }
    public string ApiUrl { get; set; }

    public InvalidStatusCodeException(HttpStatusCode receivedStatusCode, string apiUrl)
    {
        ReceivedStatusCode = receivedStatusCode;
        ApiUrl = apiUrl;
    }
}

在某些情况下扔掉它:

        string url = "api/group/1/getAll";
        var response = await _client.GetAsync(url);
        if (!response.IsSuccessStatusCode)
            throw new InvalidStatusCodeException(response.StatusCode, url);

如果我捕获并记录此异常:

        catch(InvalidStatusCodeException status_ex)
        {
            string error = $"Invalid Status code for request: '{status_ex.ApiUrl}', received code: {status_ex.ReceivedStatusCode}";
            log.LogError(status_ex, error, "InvalidStatusCode");
        }

我看不到自定义属性(ReceivedStatusCode、ApiUrl)的值,只能在错误消息中查看详细信息。

如果我根本没有捕获此异常并且异常正在自动记录,那么根本无法查看详细信息。

有什么方法可以在不额外捕获异常的情况下查看这些自定义属性?

c# azure-application-insights
3个回答
1
投票

您可以使用结构日志记录的概念,将命名常量记录为自定义属性。

catch(InvalidStatusCodeException status_ex)
{
     log.LogError(status_ex, "Invalid Status code for request: '{ApiUrl}', received code: {ReceivedStatusCode}", status_ex.ApiUrl, status_ex.ReceivedStatusCode);
 }

上述日志将在应用程序洞察日志中添加

ApiUrl
ReceivedStatusCode
作为自定义属性。

更新

您不需要抛出并捕获异常。您可以登录

if (response.IsSuccessStatusCode)
的else块,如下所示:

 if (response.IsSuccessStatusCode)
 {
     
 }
 else
 {
     log.LogError(status_ex, "Invalid Status code for request: '{ApiUrl}', received code: {ReceivedStatusCode}",
         apiUrl, response.StatusCode);
 }

记录自定义属性的其他方式是通过 Logging Scope(检查this)和通过 TelemetryInitializer(检查this


1
投票

向底座添加消息

Exception

public class InvalidStatusCodeException : Exception
{
    public HttpStatusCode ReceivedStatusCode { get; set; }
    public string ApiUrl { get; set; }

    public InvalidStatusCodeException(HttpStatusCode receivedStatusCode, string apiUrl) 
        : base($"Invalid Status code for request: '{apiUrl}', received code: {receivedStatusCode}")
    {
        ReceivedStatusCode = receivedStatusCode;
        ApiUrl = apiUrl;
    }
}

0
投票

您可以为此编写一个自定义的中间件。有3个步骤:

  • 创建自定义遥测中间件,它指定您想要从请求中捕获的内容
  • 将其注册为中间件扩展
  • 注册您的中间件以供服务器使用。

第 1 步:自定义您要捕获的遥测数据:

public class CustomTelemetryMiddleware
{
    private readonly RequestDelegate _next;

    public CustomTelemetryMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    // https://github.com/microsoft/ApplicationInsights-aspnetcore/issues/686#issuecomment-530353448
    public async Task Invoke(HttpContext context)
    {
        var requestTelemetry = context.Features.Get<RequestTelemetry>();
        if (requestTelemetry != null)
        {
            var request = context.Request;

            // add items to show up in Request Properties:
            requestTelemetry.Context.User.Id = context.User.Identity.Name;

            // add items to show up in Custom Properties:
            requestTelemetry.Properties.Add("PayingCustomer", "Yes");

            /* Capture the request body as a Custom Property
             */
            if (request?.Body?.CanRead == true)
            {
                request.EnableBuffering();

                var bodySize = (int)(request.ContentLength ?? request.Body.Length);
                if (bodySize > 0)
                {
                    request.Body.Position = 0;
                    byte[] body;
                    using (var ms = new MemoryStream(bodySize))
                    {
                        await request.Body.CopyToAsync(ms);
                        body = ms.ToArray();
                    }
                    request.Body.Position = 0;

                    var requestBodyString = Encoding.UTF8.GetString(body);
                    requestTelemetry.Properties.Add("RequestBody", requestBodyString);
                }
            }
        }
        await _next(context);
    }
}

第2步,注册:

public static class CustomTelemetryMiddlewareExtensions
{
    public static IApplicationBuilder UseCustomTelemetry(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CustomTelemetryMiddleware>();
    }
}

最后,第 3 步,在 Startup.cs 中注册它

public async void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApiVersionDescriptionProvider provider)
{
  // put this towards the end of your pipeline
  app.UseCustomTelemetry();
}
© www.soinside.com 2019 - 2024. All rights reserved.