0

Upon unexpected error which sends the user to an error page, I want to show an error id for the user to give to the customer support for further investigation.

Telemetries has itemId which is unique (guid). Is there a to fetch this itemId (or any other unique identifier) right after I track the exception telemetry?

As a workaround I thought about generating my own unique identifier and adding it to the telemetry's custom properties, but it seems like I can't look up a telemetry by a custom property.

    private string LogTelemetry(Exception ex)
    {
        var telemetryClient = new TelemetryClient();
        var telemetry = new ExceptionTelemetry(ex);

        telemetryClient.TrackException(telemetry);

        //here I want to be able to return the telemetry's unique identifier
    }
yarinsn
  • 78
  • 8
  • Hi Yarinsn, where do you find the itemId? I did not find it in code or azure portal. Or can you use the `Context.Operation.Id` as unique identifier? – Ivan Glasenberg Sep 06 '18 at 06:58
  • Thanks for your comment Ivan. I use Application Insights Analytics to analyze my logs (on VS, right-click the project in question -> Application Insights -> Application Analytics will open the tool in the browser). Over there, when I query my exceptions, one of the exception's fields is itemId, which is a Guid. About `Context.Operation.Id`, it's null in my case - Thoughts regarding that – yarinsn Sep 11 '18 at 01:18
  • I will take a try with app insights API to fetch Itemid, and will let you know if it works. – Ivan Glasenberg Sep 11 '18 at 02:32
  • please take a look at my answer below – Ivan Glasenberg Sep 12 '18 at 00:39
  • does it work for you? – Ivan Glasenberg Sep 13 '18 at 09:19
  • Using the REST api doesn't help in my case but I appreciate your detailed answer. About the link you shared regarding the operation_id, it helped me look at my situation in a different way, which resulted in me solving my problem. I will share my solution soon. Thanks for your help Ivan! – yarinsn Sep 25 '18 at 03:59
  • Congrats and thanks for your sharing :) – Ivan Glasenberg Sep 25 '18 at 05:07

2 Answers2

0

1.The ItemId can be fetched by using Application Insights REST API, but it has some time(around a few minutes) delay in runtime. The code is in the following.

2.Without using ItemId, you can use the operation_id, in your code, just use this line of code return System.Diagnostics.Activity.Current.RootId, here is reference about operation_id

3.Example for using APP Insights REST API:

3.1 Getting your API key and Application ID, details here: Nav to azure portal -> go to your application insights -> under configure section, select API Access -> Write down the application id, then click Create API Key, screenshot below, remember write down the key: enter image description here

3.2 Construct the api url, like this:

https://api.applicationinsights.io/v1/apps/your_application_id/query?,

then construct your query string:

query=exceptions | where timestamp >= datetime("UTC time") | where operation_Id == "operation_id"

you can modify the query as you need.

3.3 My code as following, it returns json string, you can parse json to get ItemId:

public string MakeException()

{

    try
    {
        int zipcode = int.Parse("123er");
    }
    catch (Exception ex)
    {

        DateTime dt = DateTime.UtcNow;
        string timeFormat = dt.ToString("s"); 

        telemetry.TrackException(ex);
        telemetry.Flush();
        System.Threading.Thread.Sleep(TimeSpan.FromMinutes(5));  // in runtime, need to wait for the result populated           

        string operation_id = System.Diagnostics.Activity.Current.RootId; //get the operation_id, will use it in the query string

        string api = "https://api.applicationinsights.io/v1/apps/your_application_id/query?";
        string query = @"query=exceptions | where timestamp >= datetime(""" + timeFormat + @""")";
        query += " | where operation_Id == " + "\"" + operation_id + "\"";
        api += query;

        string apikey = "your api key";

        //call the REST API
        HttpClient client = new HttpClient();
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Add("x-api-key", apikey);
        var req = string.Format(api);
        HttpResponseMessage response = client.GetAsync(req).Result;

        if (response.IsSuccessStatusCode)
        {
            return response.Content.ReadAsStringAsync().Result; // return a json string, you can parse it to get the ItemId
        }
        else
        {
            return response.ReasonPhrase;
        }


    }

    return "ok";
}
Ivan Glasenberg
  • 29,865
  • 2
  • 44
  • 60
0

So my solution for this problem is comprised of two parts:

  1. Adding a unique identifier (Guid) to every request using HttpContext.Current.Items (based on one of the answers to this SO question) on my app's Application_BeginRequest.

  2. Acquiring the request's unique identifier upon logging an exception, assigning it to the TelemetryClient's operation id, which is being assigned to the telemetry object, and returning it.

    private string LogTelemetry(Exception ex)
    {
        var telemetryClient = new TelemetryClient();
        var telemetry = new ExceptionTelemetry(ex);
    
        var operationId = HttpContext.Current.Items["RequestIdentity"].ToString();
        telemetryClient.Context.Operation.Id = operationId;
    
        telemetryClient.TrackException(telemetry);
    
        return operationId;
    }
    

Note that I didn't use System.Diagnostics.Activity.Current.RootId as the telemetry's operation id because the Current object was null in my case, a problem I decided not to tackle at this point.

yarinsn
  • 78
  • 8