📝

C# から Azure の Log Analytics にクエリを投げる

2021/08/19に公開

ここを見ながらやっていきます。

https://dev.loganalytics.io/documentation/Tools/CSharp-Sdk

コンソールアプリプロジェクトに以下の参照を追加します。

  • Microsoft.Azure.OperationalInsights
  • Microsoft.Rest.ClientRuntime.Azure.Authentication

アプリ内にキーやらなんやらを埋め込むと、めんどくさいので今回作る例ではユーザーシークレットから読み込むようにしておこうと思います。なので以下のパッケージも追加しておきます。

  • Microsoft.Extensions.Configuration.UserSecrets
  • Microsoft.Extensions.Configuration.Binder

ユーザーシークレットには以下のような感じのデータがあることを想定して置く感じでコードを書いていきましょう。

{
  "WorkspaceId": "",
  "ClientId": "",
  "ClientSecret": "",
  "AADDomain": ""
}

WorkspaceId はクエリを発行したい Log Anayltics を Azure ポータルで開くとワークスペース ID が確認できます。ClientId と ClientSecret は Azure AD に作成したアプリから取得してください。AADDomain はアプリを作成した Azure AD のドメインで xxxx.onmicrosoft.com 等になると思います。Azure AD に作成したアプリは Log Analytics に対してクエリが発行できるように Log Analytics 閲覧者の権限を付与しておいてください。

では、コードを書いていきましょう。まずは、ユーザーシークレットの情報を格納するためのクラスを作っておきます。

namespace LogAnalyticsQuerySample
{
    public class AppSettings
    {
        public string? WorkspaceId { get; set; }
        public string? ClientId { get; set; }
        public string? ClientSecret { get; set; }
        public string? AADDomain { get; set; }
    }
}

そして、ドキュメントにあるコードをちょと変えてユーザーシークレットから設定を読むようにしましょう。

using LogAnalyticsQuerySample;
using Microsoft.Azure.OperationalInsights;
using Microsoft.Extensions.Configuration;
using Microsoft.Rest.Azure.Authentication;

var appSettings = new ConfigurationBuilder()
    .AddUserSecrets("83eed9c3-f345-4885-b870-5d136678d5fd")
    .Build()
    .Get<AppSettings>();

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

var creds = await ApplicationTokenProvider.LoginSilentAsync(
    appSettings.AADDomain,
    appSettings.ClientId,
    appSettings.ClientSecret,
    adSettings);

var client = new OperationalInsightsDataClient(creds);
client.WorkspaceId = appSettings.WorkspaceId;

var results = client.Query("union * | take 5");

Console.WriteLine(results);

実行すると以下のような結果になりました。

Microsoft.Azure.OperationalInsights.Models.QueryResults

何か取れてるようですね。デバッガーで覗いてみると QueryResults の Results プロパティが IEnumerable<IDictionary<string, string>> になっていて、ここに結果が入っているようです。

ということで、必ず入っていると思われる TimeGenerated と Type を出してみるようにコードを変えていきます。

using LogAnalyticsQuerySample;
using Microsoft.Azure.OperationalInsights;
using Microsoft.Extensions.Configuration;
using Microsoft.Rest.Azure.Authentication;

var appSettings = new ConfigurationBuilder()
    .AddUserSecrets("83eed9c3-f345-4885-b870-5d136678d5fd")
    .Build()
    .Get<AppSettings>();

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

var creds = await ApplicationTokenProvider.LoginSilentAsync(
    appSettings.AADDomain,
    appSettings.ClientId,
    appSettings.ClientSecret,
    adSettings);

var client = new OperationalInsightsDataClient(creds);
client.WorkspaceId = appSettings.WorkspaceId;

var results = client.Query("union * | take 5");

foreach (var record in results.Results)
{
    Console.WriteLine("---------");
    if (record.TryGetValue("TimeGenerated", out var timeGenerated))
    {
        Console.WriteLine(timeGenerated);
    }

    if (record.TryGetValue("Type", out var type))
    {
        Console.WriteLine(type);
    }
}

実行すると以下のような結果になりました。

---------
2021-07-23T10:45:09.387Z
AppMetrics
---------
2021-06-09T23:39:35.966Z
AppExceptions
---------
2021-06-09T23:39:35.976Z
AppExceptions
---------
2021-06-09T23:39:43.179Z
AppExceptions
---------
2021-06-09T23:39:43.182Z
AppExceptions

感想

Log Analytics の REST API はあると思ってたけど C# SDK があるのは嬉しい誤算でした。

ソース

ソースコードは以下のリポジトリに公開しています。

https://github.com/runceel/LogAnalyticsQuerySample

Microsoft (有志)

Discussion