johnweeder
johnweeder

Reputation: 506

Given an Applications Insight Instrumentation key, get the name of the service in Azure

How can I programmatically determine the name of the Application Insights instance given the instrumentation key?

Our company has a large number of application insights instances in Azure. When troubleshooting an application, it can take quite a while to track down the right app insights instance for a particular app.

I should have specified (more than just using C# tag), that I was looking for a C# solution. Ideally, I would like to embed something so I could implement a page like 'myapp.com/appinsights' and this would give me the correct app insights instance (of the hundreds that we have) for a given app.

Upvotes: 29

Views: 21161

Answers (9)

CaptainCsaba
CaptainCsaba

Reputation: 496

I'm a bit late for an answer but another way you can find out easily without having to install anything is by opening the Azure Resource Graph Explorer tool on the Azure Portal. There you can do a query for resources by the instrumentationKey:

resources  
| where type =~ 'microsoft.insights/components'  
| project name, instrumentationKey = properties.InstrumentationKey, resourceGroup  
| where instrumentationKey == 'your-instrumentation-key' 

Upvotes: 1

logeshpalani31
logeshpalani31

Reputation: 1620

In Visual Studio code, install Azure Developer Cli and Azure Cli Tools extension, plus execute brew install azure-cli in a command line

# Set your subscription ID and Instrumentation Key
subscriptionId="<subscriptionId>"
instrumentationKey="<instrumentationKey>"

# Login to Azure
az login

# Set the subscription
az account set --subscription $subscriptionId

# Get all Application Insights in the subscription
appInsights=$(az monitor app-insights component show --query "[?instrumentationKey=='$instrumentationKey'].[appName]" --output tsv)
#or 
az monitor app-insights component show --output table | grep InstrumentationKey=$instrumentationKey

echo "Application Insights Name: $appInsights"

Upvotes: 0

Varun Sharma
Varun Sharma

Reputation: 2759

You can use the following C# program to get the application insights instance name given the instrumentation key. It doesn't require you to install any package. You just need to get the token first using the following commands provided you have Azure CLI installed.

az login
az account get-access-token --output json | ConvertFrom-Json

And then replace the token in the below code in the first line of the main function.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;

namespace FindAppInsights;

class SubscriptionList
{
    [JsonPropertyName("value")]
    public List<Subscription> Subscriptions { get; set; }
}

class Subscription
{
    [JsonPropertyName("subscriptionId")]
    public string SubscriptionId { get; set; }

    [JsonPropertyName("displayName")]
    public string DisplayName { get; set; }
}

class AppInsightsList
{
    [JsonPropertyName("value")]
    public List<AppInsights> AppInsights { get; set; }
}

class AppInsights
{
    [JsonPropertyName("id")]
    public string Id { get; set; }

    [JsonPropertyName("name")]
    public string Name { get; set; }

    [JsonPropertyName("properties")]
    public AppInsightsProperties Properties { get; set; }
}

class AppInsightsProperties
{
    [JsonPropertyName("InstrumentationKey")]
    public string InstrumentationKey { get; set; }
}

public class Program
{
    public static async Task Main()
    {
        string token = "xxxxxxxxxxxxxxxxxxxx";
        Console.Write("Enter instrumentation key - ");
        string instrumentationKey = Console.ReadLine();
        HttpClient client = new HttpClient();
        Uri baseUri = new Uri(@"https://management.azure.com/subscriptions?api-version=2020-01-01");
        client.BaseAddress = baseUri;
        client.DefaultRequestHeaders.Clear();
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        var response = await client.GetAsync(baseUri);
        var data = await response.Content.ReadAsStringAsync();
        var listOfSubscriptions = JsonSerializer.Deserialize<SubscriptionList>(data) ?? new SubscriptionList();

        foreach (var subscription in listOfSubscriptions.Subscriptions)
        {
            Console.WriteLine($"Searching for instrumentation key {instrumentationKey} in subscription - {subscription.DisplayName}");
            HttpClient appInsightsClient = new HttpClient();
            var appInsightsUri = new Uri(@$"https://management.azure.com/subscriptions/{subscription.SubscriptionId}/providers/Microsoft.Insights/components?api-version=2015-05-01");
            appInsightsClient.BaseAddress = appInsightsUri;
            appInsightsClient.DefaultRequestHeaders.Clear();
            appInsightsClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
            response = await appInsightsClient.GetAsync(appInsightsUri);
            data = await response.Content.ReadAsStringAsync();
            var appInsightsInstances = JsonSerializer.Deserialize<AppInsightsList>(data) ?? new AppInsightsList();
            var instance = appInsightsInstances.AppInsights.FirstOrDefault(x => string.Equals(x.Properties.InstrumentationKey, instrumentationKey, StringComparison.OrdinalIgnoreCase));
            if (instance != null)
            {
                Console.WriteLine($"Found app insights instance {instance.Name} with instrumentation key {instance.Properties.InstrumentationKey} in subscription {subscription.DisplayName}");                    
            }
        }

        Console.WriteLine($"No app insights instance with instrumentation key - {instrumentationKey} found");
    }
}

Upvotes: 0

caveman_dick
caveman_dick

Reputation: 6637

This is quite simple using the azure CLI:

az monitor app-insights component show --query "[?instrumentationKey=='471b5965-ce0a-4718-9bce-dc4dbcb4255f'].[applicationId, instrumentationKey]"

or you can list all of your app insights instances out using:

az monitor app-insights component show --query "[].[applicationId, instrumentationKey]"

Upvotes: 13

Tobias J
Tobias J

Reputation: 22813

The older AzureRM PowerShell module is being replaced by the new cross-platform Az module. Based on the answers of @tobias and @ranieuwe, the following can fetch all your InstrumentationKeys using the newer module.

Install the Az module

Install-Module -Name Az -AllowClobber as admin, or

Install-Module -Name Az -AllowClobber -Scope CurrentUser as non-admin

Full instructions here: https://learn.microsoft.com/en-us/powershell/azure/install-az-ps

Remove older AzureRM module if needed

If you get warnings about both Az and AzureRM being installed/loaded, you can uninstall the old module by running the following as admin: Uninstall-AzureRm

Login to Azure and select Instrumentation Keys

Import-Module Az
Connect-AzAccount
Get-AzSubscription # will list all currently connected subscriptions
Select-AzSubscription <subscription-id>

# Retrieve all Instrumentation Keys along with name of AppInsights resource
Get-AzResource -ExpandProperties -ResourceType "microsoft.insights/components" | Select -ExpandProperty Properties | Select Name, InstrumentationKey

# Find a specific Instrumentation Key
Get-AzResource -ExpandProperties -ResourceType "microsoft.insights/components" | Select -ExpandProperty Properties | Where InstrumentationKey -eq "abe66a40-c437-4af1-bfe9-4b72bd6b94a1"| Select Name, InstrumentationKey

Upvotes: 25

kayjtea
kayjtea

Reputation: 3129

Using azure cloud shell (or any shell where you have azure-cli ^2.0.64 installed):

az extension add --name application-insights
az monitor app-insights component show --output table | grep <instrumentation_key>

This searches across your current subscription. You can see your current subscription with

az account show

There are probably fancier ways to use --query but the above approach is general purpose.

Upvotes: 21

Tobias J
Tobias J

Reputation: 22813

As far as obtaining the name of your App Insights instance using the Instrumentation Key via C#, I was able to cobble together the following program. The documentation for the Azure SDK is very hit-or-miss, and the NuGet packages are still in preview.

Install the NuGet Packages

PM> Install-Package Microsoft.Azure.Management.ApplicationInsights -IncludePrerelease
PM> Install-Package Microsoft.Azure.Services.AppAuthentication -IncludePrerelease

Retrieve App Insights Components

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.Management.ApplicationInsights.Management;
using Microsoft.Azure.Management.ApplicationInsights.Management.Models;
using Microsoft.Azure.Services.AppAuthentication;
using Microsoft.Rest;

namespace CoreConsoleApp
{
    internal class Program
    {
        private static async Task Main(string[] args)
        {
            // NOTE - see below
            var auth = new AzureServiceTokenProvider();

            const string url = "https://management.azure.com/";

            var token = await auth.GetAccessTokenAsync(url);

            var cred = new TokenCredentials(token);

            var client = new ApplicationInsightsManagementClient(cred)
            {
                SubscriptionId = "<your-subscription-id>",
            };

            var list = new List<ApplicationInsightsComponent>();

            var all = await client.Components.ListAsync();
            list.AddRange(all);

            foreach(var item in list)
            {
                Console.WriteLine($"{item.Name}: {item.InstrumentationKey}");
            }
        }
    }
}

(Note that you need to be using C# 7.1 or later to have an async Task Main in your console app).

A Note on Authentication: The AzureServiceTokenProvider constructor takes an optional connection string to authenticate with Azure. It worked without one for me since I had used az login via the Azure CLI. There are quite a few other ways to get credentials, some of which are discussed in the Java client docs.

I'm sure there's a more efficient way to query just the InstrumentationKey you want using an OData query, but I wasn't able to figure out how to make that work.

There is a more general ResourceManagementClient in the Microsoft.Azure.Management.ResourceManager package, which would let you do something like the following:

var client = new Microsoft.Azure.Management.ResourceManager.ResourceManagementClient(cred) { SubscriptionId = "<your-subscription-id>" };

var query = new ODataQuery<GenericResourceFilter>(o => o.ResourceType == "microsoft.insights/components")
{
    Filter = "", // filter by Instrumentation Key here?
    Expand = "$expand=Properties",
};

using (var resp = await client.Resources.ListWithHttpMessagesAsync(query))
{
    foreach (var item in resp.Body)
    {
        Console.WriteLine($"Instance name is {item.Name}");
    }
}

Finally, this project has some other examples which may be useful.

Upvotes: 1

Tobias
Tobias

Reputation: 5108

As per @mafue's comment, the following powershell commands let you find instrumentation keys across resource groups:

Import-Module -Name AzureRM
Login-AzureRmAccount
Select-AzureRmSubscription <subscription id> 

Find-AzureRmResource -ExpandProperties -ResourceType "microsoft.insights/components" | select -ExpandProperty Properties | Select Name, InstrumentationKey

Upvotes: 3

ranieuwe
ranieuwe

Reputation: 2296

You can do this using PowerShell with the AzureRm cmdlets. If you are new to that, take a look here at the Azure Resource Manager.

You'll first need to login with Login-AzureRmAccount and then select a subscription with Select-AzureRmSubscription

The following script will get a list of the name of each Application Insights instance and its instrumentationkey:

Get-AzureRmResource -ExpandProperties -ResourceType "microsoft.insights/components"  -ResourceGroupName "your-resource-group" | select -ExpandProperty Properties  | Select Name, InstrumentationKey

This works as follows:

  1. Get all resources of type microsoft.insight/components from within your group
  2. Expand the properties of it
  3. Find the instrumentationkey and name in the properties

Upvotes: 8

Related Questions