alexeldeib
4/24/2018 - 5:52 AM

App Insights and Log Analytics SDK + CLI Update

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:

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
        }
    }
}

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

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

            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.