OpenTelemetryに関する記事をしばらく書いていなかったので、改めて .NET 8 がリリースされた時点でのOpenTelemetry への対応についてまとめてみたいと思います。 .NET 7のときはリリースノートにもOpenTelemetry対応が記載されていたのですが、.NET 8では記載されていません。
個人的にはOpenTelemetry .NETに向けて、 .NET Runtime、SDK側での大きな対応はもう不要ということではないかと思っています。また、OpenTelemetryに関して .NET 側のドキュメントでも記載されるようになりました。そこで、これらのドキュメントを中心に .NET 8におけるOpenTelemetry対応をまとめてみることにします。長くなりそうなので、概要・メトリクス・トレース・ロギングの4回に分けて書く予定です。
.NET における監視とOpenTelemetry
OpenTelemetryの位置づけ
まず、OpenTelemetryで収集される情報の位置は、デバッガー、単体テスト、診断ツールと並んで「監視のためのインストルメンテーション」となっています。デバッガーや診断ツールが実際に動いている環境を操作したり、情報を取得したりするのに対し、遠隔からシステムの動いている状況を把握できる=テレメトリーデータの取得を実現する要素となっています。
.NETにおいてOpenTelemetryを利用した監視については以下に説明されています。
このドキュメントで改めてデバッグと監視の違いを説明しています。
侵入性があり、アプリケーションの動作に影響を与える可能性があるデバッグとは異なり、監視はプライマリ操作に対して透過的であり、パフォーマンスへの影響が継続的に使用できる程度に十分小さくなるように意図したものです。
.NETにおける監視を実現する方法はいくつかありますが、アプリケーションを再ビルドできるのであればOpenTelemetryのような明示的なコードが最も強力です。また、スタートアップフックによりアプリにアセンブリを挿入しますが、これは以前紹介したOpenTelemetry .NETの自動計装で利用されています。これらに加えて、EventPipeを利用する方法もありこれは dotnet-monitorという診断ツールで利用されています。
.NET におけるOpenTelemetryの実装
OpenTelemetryの実装において、.NETが他の言語と異なるのはOpenTelemetryのAPIを利用せずに、.NETのAPIを利用することでOpenTelemetryによる計装が可能になっている点です。
- ログはMicrosoft.Extensions.Logging.ILogger
- メトリックは System.Diagnostics.Metrics.Meter
- 分散トレースは System.Diagnostics.ActivitySource と System.Diagnostics.Activity
これらのAPIを呼び出すことで、OpenTelemetryのテレメトリーデータとして記録できる作りになっています。
OpenTelemetryの配布については、NuGetパッケージを利用しますが、用途別に分けられたパッケージ構成になっています。OpenTelemetryのコア機能を提供するOpenTelemetryをはじめとし、計装についてはOpenTelemetry.Instrumentation.xxx
という名前で提供されています。例えば、ASP.NET Coreの計装はOpenTelemetry.Instrumentation.AspNetCore、HTTPの送信の計装はOpenTelemetry.Instrumentation.Httpとなっています。
OpenTelemetryではテレメトリーデータの送信までが責務で、データの保存や可視化についてはオブザーバビリティバックエンドとよばれるツールやサービスを利用する想定です。そのためバックエンドにあわせた形式で送信するexporterとよばれる機能ごとにNuGetライブラリが提供されています。主にテスト目的でコンソールに出力するOpenTelemetry.Exporter.Console、OTLPプロトコルとよばれるOpenTelemetry標準のフォーマットで送信するOpenTelemetry.Exporter.OpenTelemetryProtocolなどが用意されています。
ドキュメントでは、OSSなオブザーバビリティバックエンドであるPrometheus・Grafana・Jaegerを利用した実装サンプルとAzure MonitorとApplication Insightsを利用した実装サンプルが用意されています。
この中でPrometheusはscrape方式(pull式)なデータ取得に対し、OpenTelemetryでは通常push方式なデータ送信であるため、OpenTelemetry.Exporter.Prometheus.AspNetCoreではASP.NET Coreのエンドポイントを利用してscrapeのためのエンドポイントを提供する実装となっています。また、Azure Monitorが専用のexporterが必要なのに対し、JaegerやNew RelicのようなOTLPプロトコルをサポートするバックエンドではOpenTelemetry.Exporter.OpenTelemetryProtocolを利用し接続先を指定するだけで送信が可能になります。