Skip to content

Instantly share code, notes, and snippets.

@alexeldeib
Last active January 26, 2021 18:09
Show Gist options
  • Save alexeldeib/7bfa6e671904cd33aaaac5c3d3ff8e09 to your computer and use it in GitHub Desktop.
Save alexeldeib/7bfa6e671904cd33aaaac5c3d3ff8e09 to your computer and use it in GitHub Desktop.
App Insights and Log Analytics SDK + CLI Update

Application Insights Query SDK

The Microsoft.Azure.ApplicationInsights NuGet package contains the query SDK for App Insights. Here's a bare-minimum setup with a client ready to make calls:

AAD Authentication

using System;
using Microsoft.Azure.ApplicationInsights;
using Microsoft.Rest.Azure.Authentication;
using System.Collections.Generic;

namespace AppInsightsSDKDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting...");

            var appId = "{appId}";
            var clientId = "{aadClientAppId}";
            var clientSecret = "{aadAppkey}";

            var domain = "microsoft.onmicrosoft.com";
            var authEndpoint = "https://login.microsoftonline.com";
            var tokenAudience = "https://api.applicationinsights.io/";
    
            var adSettings = new ActiveDirectoryServiceSettings
            {
                AuthenticationEndpoint = new Uri(authEndpoint),
                TokenAudience = new Uri(tokenAudience),
                ValidateAuthority = true
            };
            
            // Authenticate with client secret (app key)
            var creds = ApplicationTokenProvider.LoginSilentAsync(domain, clientId, clientSecret, adSettings).GetAwaiter().GetResult();

            // New up a client with credentials and AI application Id
            var client = new ApplicationInsightsDataClient(creds);
            client.AppId = appId
        }
    }
}

API Key Authentication

using System;
using Microsoft.Azure.ApplicationInsights.Models;
using Microsoft.Azure.ApplicationInsights;
using Microsoft.Rest.Azure.Authentication;
using System.Collections.Generic;

namespace AppInsightsAPIKeySDKDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting...");

            var appId = "{appId}";
            var apiKey = "{apiKey}";

            var baseUrl = "https://api.applicationinsights.io/v1";
            
            // Authenticate with api key
            var creds = new ApiKeyClientCredentials(apiKey);

            // New up a client with credentials and AI application Id
            var client = new ApplicationInsightsDataClient(new Uri(baseUrl), creds);
            client.AppId = appId
        }
    }
}

There are a few different ways to authenticate, which you can read about in the AutoRest docs. We can set up some metrics and a query to run:

var metric = "availabilityResults/duration";
var query = "availabilityResults | summarize count() by name, bin(duration,500) | order by _count desc";
var metricA = new MetricsPostBodySchema("labelYourResult", new MetricsPostBodySchemaParameters("availabilityResults/duration", new TimeSpan(6, 0, 0))); // 6hr query
var metricB = new MetricsPostBodySchema("aDifferentLabel", new MetricsPostBodySchemaParameters("availabilityResults/count"));
var metrics = new List<MetricsPostBodySchema> { metricA, metricB };

And then we can make some calls (all of which have async counterparts):

var metricResult   = client.GetMetric(metric);
var metricResult2  = client.GetMetricAsync(metric).GetAwaiter().GetResult(); // same as above
var metricsResult  = client.GetMetrics(metrics);
var eventsResult   = client.GetEvents(EventType.Requests);
var queryResults   = client.Query(query);

Take a look at the generated models to see the details of the returned object shape of these methods. As an example on usage:

for (var i = 0; i < queryResults.Tables[0].Rows.Count; i++) {
    // Do something with query results
    Console.WriteLine(String.Join("    ", queryResults.Tables[0].Rows[i]));
}

foreach (KeyValuePair<string, float> entry in metricResult.Value.MetricValues)
{
    // Print metric name and value
    Console.WriteLine(String.Format("{0}: {1}", entry.Key, entry.Value));
}

Segmented and Intervaled Metrics

The generic GetMetric(s) methods return an object of type MetricResult. While this is sufficient to describe simple metrics results, it is not the most precise representation of all results. In cases using GetMetric to query with segments and intervals, the basic method will return a bag of AdditionalProperties attached to the metrics containing the properties which are part of that particular result, but not the basic metric response.

The SDK offers convenience methods which query for segmented, intervaled, or summary metrics and return types precise to the appropriate situation. These take the same arguments as the generic form, but return more specific types.

var segmentResult  = client.GetSegmentedMetric(metric, "client/os"); // returns MetricsSegmentedResult
var intervalResult = client.GetIntervaledMetric(metric, "PT1H"); // MetricsIntervaledResult
var intervaledSegmented = client.GetIntervaledSegmentedMetric(metric, interval: new TimeSpan(6, 0, 0), segment: new List<string> { "client/os" })
var summaryResult = client.GetMetricSummary(metric)

Log Analytics Query PowerShell Cmdlet

The AzureRM.OperationalInsights module contains a cmdlet for querying Log Analytics: Invoke-AzureRmOperationalInsightsQuery

Prerequisites

Azure PowerShell is required to authenticate with the query cmdlet. On Windows, run:

Install-Module -Name AzureRM

Log into your account before querying:

Connect-AzureRmAccount

If you're using a service principal, this will probably look more like one of the following:

$creds = New-Object System.Management.Automation.PSCredential ("appIdOrLogin", (ConvertTo-SecureString "appKeyOrPassword" -AsPlainText -Force))
Login-AzureRmAccount -Credential $creds -Tenant {TenantId}

Usage

SYNTAX

Invoke-AzureRmOperationalInsightsQuery -Query <String> -Workspace <PSWorkspace> [-AsJob] [-DefaultProfile <IAzureContextContainer>] [-IncludeRender] [-IncludeStatistics] [-Timespan <TimeSpan>] [-Wait <Int32>] 
  
Invoke-AzureRmOperationalInsightsQuery -Query <String> -WorkspaceId <String> [-AsJob] [-DefaultProfile <IAzureContextContainer>] [-IncludeRender] [-IncludeStatistics] [-Timespan <TimeSpan>] [-Wait <Int32>] 

The first form takes in the Workspace to query as a PSWorkspace object rather than the GUID representing the workspace as a string. To retrieve a workspace as an object, use the Get-AzureRmOperationalInsightsWorkspace cmdlet.

The returned object contains a results property with the actual results.

$res = Invoke-AzureRmOperationalInsightsQuery -WorkspaceId "DEMO_WORKSPACE" -query "AzureActivity | take 1 "

$res.Results.OperationName
# e.g., Microsoft.Compute/restorePointCollections/restorePoints/retrieveSasUris/action

Log Analytics Query C# SDK

The Microsoft.Azure.OperationalInsights NuGet package contains a client with a single Query method and its async counterpart. Basic usage:

using System;
using Microsoft.Azure.OperationalInsights;
using Microsoft.Rest.Azure.Authentication;
using System.Collections.Generic;

namespace LogAnalyticsSDKDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting...");

            var workspaceId = "{workspaceId}";
            var clientId = "{aadClientAppId}";
            var clientSecret = "{aadAppkey}";
            
            // AAD settings, domain == tenant
            var domain = "microsoft.onmicrosoft.com";
            var authEndpoint = "https://login.microsoftonline.com";
            var tokenAudience = "https://api.loganalytics.io/";

            var adSettings = new ActiveDirectoryServiceSettings
            {
                AuthenticationEndpoint = new Uri(authEndpoint),
                TokenAudience = new Uri(tokenAudience),
                ValidateAuthority = true
            };
            
            // Authenticate with client secret (app key)
            var creds = ApplicationTokenProvider.LoginSilentAsync(domain, clientId, clientSecret, adSettings).GetAwaiter().GetResult();

            // New up a client with credentials and LA workspace Id
            var client = new OperationalInsightsDataClient(creds);
            client.WorkspaceId = workspaceId;
            
            var results = client.Query("union * | take 5");
            Console.WriteLine(results);
            // TODO process the results
        }
    }
}

The generated models contain the details of the response shape.

@girays
Copy link

girays commented Sep 2, 2020

Is the API Key Authentication scenario using C# still supported? I am getting an error when I run the sample at: https://gist.github.com/alexeldeib/7bfa6e671904cd33aaaac5c3d3ff8e09#api-key-authentication

System.Net.Http.HttpRequestException: 'No such host is known'

@alexeldeib
Copy link
Author

Unfortunately I changed teams almost a year ago, if you're ms internal i'd reach out to aiapi@microsoft.com or else I'd suggest opening an issue against either azure-rest-api-specs (if it ends up being api level) or C# sdk (if it's just a client issue).

@geneh
Copy link

geneh commented Sep 17, 2020

@girays Could you please change the baseUrl to https://api.applicationinsights.io/v1
@alexeldeib Please feel free to update your gist with the right URL.

@alexeldeib
Copy link
Author

fixed 🙂

@f2calv
Copy link

f2calv commented Jan 3, 2021

thanks @alexeldeib this is very helpful page for a jumpstart, however the API Key Authentication example needs an update before it will work...
Before;

// Authenticate with api key
var creds = ApiKeyClientCredentials(apiKey);

// New up a client with credentials and AI application Id
var client = new ApplicationInsightsDataClient(baseUrl, creds);
client.AppId = appId

After;

// Authenticate with api key
var creds = new ApiKeyClientCredentials(apiKey);

// New up a client with credentials and AI application Id
var client = new ApplicationInsightsDataClient(new Uri(baseUrl), creds);
client.AppId = appId;

@alexeldeib
Copy link
Author

👍 thanks @f2calv!

@f2calv
Copy link

f2calv commented Jan 3, 2021

np... but still missing a 'new' in front ApiKeyClientCredentials ;)

@alexeldeib
Copy link
Author

🤦‍♂️ think that's better

@afratila
Copy link

Which package contains the ApplicationInsightsDataClient class? I am working in Visual Studio and when I explore nuget packages I see Microsoft.Azure.ApplicationInsights.Query and Microsoft.ApplicationInsights, neither of which contain this class. I tried to import Microsoft.Azure.ApplicationInsights but it is not found in the nuget package list.

@geneh
Copy link

geneh commented Jan 26, 2021

Which package contains the ApplicationInsightsDataClient class? I am working in Visual Studio and when I explore nuget packages I see Microsoft.Azure.ApplicationInsights.Query and Microsoft.ApplicationInsights, neither of which contain this class. I tried to import Microsoft.Azure.ApplicationInsights but it is not found in the nuget package list.

Please check https://dev.applicationinsights.io/documentation/Tools/CSharp-Sdk and https://dev.loganalytics.io/documentation/Tools/CSharp-Sdk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment