ネコの耳に念仏

ネコの耳に念仏

ガンバらない技術ブログを目指します

【C#】OpenTelemetryで収集したアプリのメトリックをAzureMonitorへ送信する方法【.NET】

OpenTelemetry を利用して収集した C# アプリのメトリックを Azure Monitor へ送信してみたので、その送信方法を説明する。

OpenTelemetry で収集したアプリのメトリックを Azure Monitor へ送信する方法

メトリックの送信方式

OpenTelemetry を利用して収集したメトリックの送信方法は、主に下記の2方式がある。

  • アプリから Azure Monitor へ直接送信する方式
  • アプリから OpenTelemetry コレクターへ送信し、コレクターから Azure Monitor へ送信する方式

今回は、前者の「アプリから直接送信する方式」を説明する。

前提条件

まず前提条件として、下記を満たしていること。

  • Application Insights リソースが存在すること
  • .NET Core または .NET Framework (4.6.2 以上) を使用するアプリケーションであること

Application Insights の接続文字列を取得

Azure ポータルから Application Insights リソースの管理画面を開き、「概要」ペインに表示される接続文字列をコピーしておく。

アプリケーションの実装

メトリック送信を行うアプリケーションのプロジェクトに、「Azure.Monitor.Opentelemetry.Exporter」 NuGet パッケージをインストールする。

実装サンプルは下記のような感じ。

public class Program{
    static void main(string[] args)
    {
        // 初期化
        MetricsRecorder.Init();

        // Histgram のメトリックの記録
        MetricsRecorder.RecordProcessingTime();

        // Counter のメトリックの記録
        MetricsRecorder.RecordRequestCount();
    }
}
internal class MetricsRecorder
{
    /// <summary>
    /// MeterProviderを作成
    /// </summary>
    private static MeterProvider? meterProvider;

    /// <summary>
    /// Meterを作成
    /// </summary>
    private static readonly Meter meter = new Meter("MyMeter");

    /// <summary>
    /// Instrument(Histgram)を作成
    /// 同時に複数作成することができる
    /// </summary>
    private static readonly Histogram<long> processingTime = meter.CreateHistogram<long>(
        name: "ProcessingTime",
        unit: "ms",
        description: "This is processing time.");

    /// <summary>
    /// Instrument(Counter)を作成
    /// 同時に複数作成することができる
    /// </summary>
    private static readonly Counter<long> requestCount = meter.CreateCounter<long>(
        name: "RequestCount",
        unit: "times",
        description: "This is request count.");

    /// <summary>
    /// 初期化処理
    /// </summary>
    public static void Init()
    {
        // MeterProviderを作成
        // Meterを追加、Azure Monitor 向けエクスポーターを追加
        meterProvider = Sdk.CreateMeterProviderBuilder()
            .AddMeter("MyMeter")
            .AddAzureMonitorMetricExporter(options =>
            {
                options.ConnectionString = "{Application Insights の接続文字列}";
            })
            .Build();
    }

    /// <summary>
    /// Histgramのメトリック「ProcessingTime」の記録
    /// </summary>
    public static void RecordProcessingTime()
    {
        // メトリックに記録する値をランダムに作成(1~100)
        var rand = new Random();
        long value = rand.Next(1, 101);

        // ディメンションを作成(最大個数は不明だが適当に10個作成)
        KeyValuePair<string, object?>[] dimensions = new KeyValuePair<string, object?>[]
        {
            new KeyValuePair<string, object?>("DimensionName0", "DimensionValue0"),
            new KeyValuePair<string, object?>("DimensionName1", "DimensionValue1"),
            new KeyValuePair<string, object?>("DimensionName2", "DimensionValue2"),
            new KeyValuePair<string, object?>("DimensionName3", "DimensionValue3"),
            new KeyValuePair<string, object?>("DimensionName4", "DimensionValue4"),
            new KeyValuePair<string, object?>("DimensionName5", "DimensionValue5"),
            new KeyValuePair<string, object?>("DimensionName6", "DimensionValue6"),
            new KeyValuePair<string, object?>("DimensionName7", "DimensionValue7"),
            new KeyValuePair<string, object?>("DimensionName8", "DimensionValue8"),
            new KeyValuePair<string, object?>("DimensionName9", "DimensionValue9"),
        };
        
        // メトリックを記録
        processingTime.Record(value, dimensions);
    }

    /// <summary>
    /// Counterのメトリック「RequestCount」の記録
    /// </summary>
    public static void RecordRequestCount()
    {
        // メトリックに記録する値をランダムに作成(1~3)
        var rand = new Random();
        long value = rand.Next(1, 4);

        // ディメンションを作成(最大個数は不明だが適当に10個作成)
        KeyValuePair<string, object?>[] dimensions = new KeyValuePair<string, object?>[]
        {
            new KeyValuePair<string, object?>("DimensionName0", "DimensionValue0"),
            new KeyValuePair<string, object?>("DimensionName1", "DimensionValue1"),
            new KeyValuePair<string, object?>("DimensionName2", "DimensionValue2"),
            new KeyValuePair<string, object?>("DimensionName3", "DimensionValue3"),
            new KeyValuePair<string, object?>("DimensionName4", "DimensionValue4"),
            new KeyValuePair<string, object?>("DimensionName5", "DimensionValue5"),
            new KeyValuePair<string, object?>("DimensionName6", "DimensionValue6"),
            new KeyValuePair<string, object?>("DimensionName7", "DimensionValue7"),
            new KeyValuePair<string, object?>("DimensionName8", "DimensionValue8"),
            new KeyValuePair<string, object?>("DimensionName9", "DimensionValue9"),
        };

        // メトリックを記録
        requestCount.Add(value, dimensions);
    }
}

アプリケーションの実行

アプリを実行してメトリック送信してみましょう。

あっ、メトリックの送信処理が実行されるまでは待機とか入れてアプリが終了されないようにしてくださいね。 メトリックの送信間隔はデフォルトで60秒です。

メトリックの送信確認

Azure Monitor へ送信したメトリックを確認してみましょう。

Azure ポータルへログインして、送信先に設定した Application Insights の管理画面を開いてください。

左ペインメニューの「メトリック」を開きます。

「メトリックの追加」設定欄で下記のように選択し、メトリックがグラフに表示されれば成功です。

  • スコープ : {メトリック送信先に設定した Application Insights のリソース名}
  • メトリック名前空間 : ログベースのメトリック
  • メトリック : {アプリで設定したメトリック名}

また、ディメンションで分割したい場合は、「分割を適用する」をクリックして、設定欄の「値」で任意のディメンションを選択します。

以上