'Get exception details from Azure Monitor Workbook that deals with multiple app insight instances

I am working on creating a workbook that provides an umbrella view over multiple app insight instances. Our solution has many microservices (Azure functions) each having its own app insight instance. Aim of this workbook is to provide a health status for the whole app by surfacing up errors across app insight instances in to a single view.

I have used the "Failure Analysis" template to set this up. User is able to select different app insight instances at the top and the views will filter based on that. There's a view that shows exception counts with trends like this. Each error may belong to different App Insight instances.

enter image description here

When you click on a line item all instances of that error will be shown in a following view like this

enter image description here

I use the following query to load it

let row = dynamic({Row});
let req = requests
| where '{Row}' == '{}' or (row.Kind == 'Application' and row.Id 
    == appName) or (row.Kind == 'Request' and row.Id ==    
    strcat(appName, "::", name))
| where success == "False";

 let errors = exceptions
 | where appName == appName 
 | where timestamp between({TimeRange:start}..{TimeRange:end});

 errors
 | join req on operation_Id
 | project operation_Id, itemId, timestamp,requestName=name, 
        exception=type, method, outerMessage, innermostMessage, 
        details, appName

As mentioned in this question Get exception details from a Azure Monitor Workbook, the itemId is available and I try to link it to the "Exception Details" view. Please note that these errors can come from one of many App Insight instances based on what gets selected at the previous view.

I have configured the item Id and appName columns as follows using Link renderer and Automatic renderer.

enter image description here enter image description here

However the link always directs to one specific app insight instance (Not the one associated with the error) and hence the error won't get loaded. Is it possible to load the "Detail Views" across App Insight instances using this technique? If not what could be other avenues? enter image description here



Solution 1:[1]

When the application insights is workspace based, each telemetry item has a field _ResourceId that contains a link to the resource, for example

/subscriptions/c8vfbeab-a5a67-4272-aa6e-4c9f4142e962/resourcegroups/rg-my-resource-group/providers/microsoft.insights/components/my-ai-resource

You can use this a part of the url to create a deep link to the details page of the Application Insights resource of the telemetry with the specified item id. Take this query for example:

exceptions
| take 1
| extend portalUrl = strcat("https://portal.azure.com/#blade/AppInsightsExtension/BladeRedirect/BladeName/searchV1/ResourceId/", url_encode(_ResourceId), "/BladeInputs/%7B%22tables%22%3A%5B%22availabilityResults%22%2C%22requests%22%2C%22exceptions%22%2C%22pageViews%22%2C%22traces%22%2C%22customEvents%22%2C%22dependencies%22%5D%2C%22timeContextWhereClause%22%3A%22%7C%20where%20timestamp%20%3E%20datetime(%5C%222022-02-12T12%3A55%3A02.739Z%5C%22)%20and%20timestamp%20%3C%20datetime(%5C%222022-03-14T12%3A55%3A02.739Z%5C%22)%22%2C%22filterWhereClause%22%3A%22%7C%20where%20*%20has%20%5C%22a1a20ad1a12ff348a852288a4d9953a5%5C%22%7C%20order%20by%20timestamp%20desc%22%2C%22originalParams%22%3A%7B%22eventTypes%22%3A%5B%7B%22value%22%3A%22availabilityResult%22%2C%22tableName%22%3A%22availabilityResults%22%2C%22label%22%3A%22Availability%22%7D%2C%7B%22value%22%3A%22request%22%2C%22tableName%22%3A%22requests%22%2C%22label%22%3A%22Request%22%7D%2C%7B%22value%22%3A%22exception%22%2C%22tableName%22%3A%22exceptions%22%2C%22label%22%3A%22Exception%22%7D%2C%7B%22value%22%3A%22pageView%22%2C%22tableName%22%3A%22pageViews%22%2C%22label%22%3A%22Page%20View%22%7D%2C%7B%22value%22%3A%22trace%22%2C%22tableName%22%3A%22traces%22%2C%22label%22%3A%22Trace%22%7D%2C%7B%22value%22%3A%22customEvent%22%2C%22tableName%22%3A%22customEvents%22%2C%22label%22%3A%22Custom%20Event%22%7D%2C%7B%22value%22%3A%22dependency%22%2C%22tableName%22%3A%22dependencies%22%2C%22label%22%3A%22Dependency%22%7D%5D%2C%22timeContext%22%3A%7B%22durationMs%22%3A2592000000%7D%2C%22filter%22%3A%5B%5D%2C%22searchPhrase%22%3A%7B%22originalPhrase%22%3A%22", itemId,"%22%2C%22_tokens%22%3A%5B%7B%22conjunction%22%3A%22and%22%2C%22value%22%3A%22a1a20ad1a12ff348a852288a4d9953a5%22%2C%22isNot%22%3Afalse%2C%22kql%22%3A%22%20*%20has%20%5C%22a1a20ad1a12ff348a852288a4d9953a5%5C%22%22%7D%5D%7D%2C%22sort%22%3A%22desc%22%7D%7D")
| project timestamp,  problemId, itemId, portalUrl

If you create a workbook and render a table based on the query above you have to modify the itemId column to be a link like this:

enter image description here

Clicking the itemId column it should open the correct Application Insights resource details page:

enter image description here

enter image description here

Now, I hope this give you enough clues to extend your own queries by including the deep link url in your query output.

For completeness, this is the full workbook Gallery Template:

{
  "version": "Notebook/1.0",
  "items": [
    {
      "type": 3,
      "content": {
        "version": "KqlItem/1.0",
        "query": "exceptions\n| take 1\n| extend portalUrl = strcat(\"https://portal.azure.com/#blade/AppInsightsExtension/BladeRedirect/BladeName/searchV1/ResourceId/\", url_encode(_ResourceId), \"/BladeInputs/%7B%22tables%22%3A%5B%22availabilityResults%22%2C%22requests%22%2C%22exceptions%22%2C%22pageViews%22%2C%22traces%22%2C%22customEvents%22%2C%22dependencies%22%5D%2C%22timeContextWhereClause%22%3A%22%7C%20where%20timestamp%20%3E%20datetime(%5C%222022-02-12T12%3A55%3A02.739Z%5C%22)%20and%20timestamp%20%3C%20datetime(%5C%222022-03-14T12%3A55%3A02.739Z%5C%22)%22%2C%22filterWhereClause%22%3A%22%7C%20where%20*%20has%20%5C%22a1a20ad1a12ff348a852288a4d9953a5%5C%22%7C%20order%20by%20timestamp%20desc%22%2C%22originalParams%22%3A%7B%22eventTypes%22%3A%5B%7B%22value%22%3A%22availabilityResult%22%2C%22tableName%22%3A%22availabilityResults%22%2C%22label%22%3A%22Availability%22%7D%2C%7B%22value%22%3A%22request%22%2C%22tableName%22%3A%22requests%22%2C%22label%22%3A%22Request%22%7D%2C%7B%22value%22%3A%22exception%22%2C%22tableName%22%3A%22exceptions%22%2C%22label%22%3A%22Exception%22%7D%2C%7B%22value%22%3A%22pageView%22%2C%22tableName%22%3A%22pageViews%22%2C%22label%22%3A%22Page%20View%22%7D%2C%7B%22value%22%3A%22trace%22%2C%22tableName%22%3A%22traces%22%2C%22label%22%3A%22Trace%22%7D%2C%7B%22value%22%3A%22customEvent%22%2C%22tableName%22%3A%22customEvents%22%2C%22label%22%3A%22Custom%20Event%22%7D%2C%7B%22value%22%3A%22dependency%22%2C%22tableName%22%3A%22dependencies%22%2C%22label%22%3A%22Dependency%22%7D%5D%2C%22timeContext%22%3A%7B%22durationMs%22%3A2592000000%7D%2C%22filter%22%3A%5B%5D%2C%22searchPhrase%22%3A%7B%22originalPhrase%22%3A%22\", itemId,\"%22%2C%22_tokens%22%3A%5B%7B%22conjunction%22%3A%22and%22%2C%22value%22%3A%22a1a20ad1a12ff348a852288a4d9953a5%22%2C%22isNot%22%3Afalse%2C%22kql%22%3A%22%20*%20has%20%5C%22a1a20ad1a12ff348a852288a4d9953a5%5C%22%22%7D%5D%7D%2C%22sort%22%3A%22desc%22%7D%7D\")\n| project timestamp,  problemId, itemId, portalUrl",
        "size": 1,
        "timeContext": {
          "durationMs": 86400000
        },
        "queryType": 0,
        "resourceType": "microsoft.insights/components",
        "gridSettings": {
          "formatters": [
            {
              "columnMatch": "problemId",
              "formatter": 1,
              "formatOptions": {
                "linkColumn": "portalUrl",
                "linkTarget": "Url"
              }
            }
          ]
        }
      },
      "name": "query - 2"
    }
  ],
  "fallbackResourceIds": [
    "/subscriptions/4547474-1a67-4272-aa6e-4c9f4142e269/resourceGroups/rg-resourcegroup-prod/providers/microsoft.insights/components/appi-demo-prod"
  ],
  "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json"
}

Solution 2:[2]

It looks like from a quick perusal of the code, that if you also have an appName column in the row where itemId is, it will try to look in the resource list used in the query to try to find a resource with that same name, and if not, just take the first one it can find?

but i see that you have appName there, but i'm not sure the rest of the configuration from your step? are you also using all of the resources in the query?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 John Gardner