【问题标题】:Application insights and custom properties of Exception异常的应用洞察和自定义属性
【发布时间】:2021-01-03 14:25:14
【问题描述】:

我有以下异常:

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)的值,只能在错误消息中看到详细信息。

如果我根本没有捕捉到这个异常并且异常被自动记录,那么根本无法查看详细信息。

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

【问题讨论】:

  • “我看不到自定义属性的值”在哪里看不到?观察窗?调试窗口?输出?
  • @Charlieface 添加了
  • @OlegSh,也可以考虑使用this method

标签: c# azure-application-insights


【解决方案1】:

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

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

以上日志将在应用洞察日志中添加ApiUrlReceivedStatusCode 作为自定义属性。

更新

您不要抛出和捕获异常。您可以登录if (!response.IsSuccessStatusCode)的else块,如下所示:

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

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

【讨论】:

  • 我使用了相同的方法,但首先,自定义属性没有保存(仅作为消息字符串),其次,我必须捕获并重新抛出此异常
  • @OlegSh - 我注意到,在LogError 中,使用了字符串插值。变量作为参数传递,{} 包含字符串文字,这些将被记录为自定义属性。你用过同样的方法吗?
  • 是的,你是对的。但我想完全避免捕获错误并编写自定义属性。有可能吗?
  • 因此您不需要抛出异常。您可以在 `if (!response.IsSuccessStatusCode)` 代码条件的 else 条件中添加日志。记录自定义属性的另一种方式是Logging Scope(检查this)和通过TelemetryInitializer(检查this
  • 另一种方法是在发送请求和接收响应时使用DelegatingHandler 记录条目。在here查看示例实现。
【解决方案2】:

添加消息到基地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;
    }
}

【讨论】:

  • 可能,这是一个解决方案。但无论如何我都想保存 App Insights 自定义属性,并且不想在异常级别准备消息(无法排序/过滤,可以是本地化等)
猜你喜欢
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多