Search code examples
c#azure-application-insights

Application insights and custom properties of Exception


I have the following exception:

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

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

throw it in some cases:

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

if I catch and log this exception:

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

I don't see values of my custom properties (ReceivedStatusCode, ApiUrl) and can see details only in error message.

enter image description here

If I don't catch this exception at all and exception is being logged automatically then no way to see details at all.

Any way to see these custom properties without additional catching of exception?


Solution

  • You can use the concept of structure logging which logs the named constant as custom properties.

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

    The above log will add ApiUrl and ReceivedStatusCode as custom properties in application insights log.

    Update

    You don't need to throw and catch the exception. You can log in the else block of if (response.IsSuccessStatusCode) like shown below:

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

    Other way of logging custom properties is via Logging Scope (check this) and via TelemetryInitializer (check this)