銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

OpenTelemetry .NETを理解する (1) OpenTelemetryとは

f:id:tanaka733:20220106001746p:plain OpenTelemetry .NETを使って.NETアプリケーションを計測する方法について複数回にわたって紹介してみたいと思います。まず .NET向けの話に行く前に、OpenTelemetryそのものについてかんたんにまとめてみます。

OpenTelemetryの誕生

アプリケーションのパフォーマンスを計測し監視するためには、それまであったプロセスやネットワークの死活監視では不十分でした。Webアプリケーションの例では、1つのHTTPリクエストに対しどのくらいのレスポンスで返しているのか、そこでのボトルネックはコードのどの部分に対応するのか、あるアプリケーションは時間あたりどの程度のリクエストを処理しているのか、といったデータを計測する必要があります。そのようなデータを計測し、監視するためのツールとして、New Relicなどのベンダーが提供するツールが出てきました。New Relicの例で言えば、New Relicの公開が2008年、.NET に対応したのが2012年になっています。

ベンダーが提供するツールは、どんなデータをどのような形式でどのように計測するかといった仕様が多くの場合公開されていません。そのため、たとえ同じデータ、例えば1つのHTTPリクエストに対する平均レスポンス時間、を計測する場合でも、あるツールから別のツールに入れ替えると計測の方法そのものをセットアップしなおす必要がありました。

GitHub上をはじめとしたオープンソースとして公開されるライブラリが増えていく中、ベンダー依存が強いツールは使う場所を選ぶようになってきました。特にライブラリ開発者にとっては、計測ツールへの対応が求められることがあっても、特定の計測ツールに依存したコードを含めてしまうのは避けたいものです。そのような事情もあり、計測ツールのオープンな標準プロジェクトが求められるようになりました。

当初(2018年ごろより)OpenCensusとOpenTracingというオープンなプロジェクトがありましたが、2019年に両者が発展的に合流したのがOpenTelemetryプロジェクトです。

opentelemetry.io

OpenTelemetryとは何なのか

OpenTelemetryのDocsの最初に記載があります。

opentelemetry.io

アプリケーションの状態を知るためのデータをテレメトリーデータ(アプリケーションから離れた場所から収集できるデータ)とし、テレメトリーデータの形式、収集方法、バックエンドへの送信方法をベンダーに依存せず標準化するためのものです。

f:id:tanaka733:20220106001214p:plain

テレメトリーデータは現在のところ、メトリクス、トレース、ログの3種類は想定されていますが、3種類に限定されたわけではありません。今後追加される可能性もあります。

opentelemetry.io

メトリクス、ログ、トレースとはなんだ?という定義については、実際にOpenTelemetryを使いながら説明することにします。今すぐ知りたいという場合は、まずこのページをおすすめします。

www.oreilly.com

また、OpenTelemetryでは対象となるアプリケーションからどのように収集し、どのように送信するか、までを設計しており、送信したあとどのように保存し活用するかについては対象外となります。送信されたテレメトリーデータを保存しUIなどに表示して活用するツールやサービスを「バックエンド」と呼んでいます。OpenTelemetryではどのバックエンドに送信するかを「エクスポーター」と呼ばれるプラグ可能な機能として提供しています。JaegerやPrometheusといったオープンソースなツールからNew Relicのような商用サービスまでさまざまなバックエンドに送信することが可能です。また、これらのツールやサービス側もOpenTelemetry標準の形式でのエクスポーターによるデータ送信が可能になるよう対応を進めています。

OpenTelemetery で計測するために必要なもの

f:id:tanaka733:20220105234322p:plain

計測するためのツールを導入していない状況で新規に導入するケース(図の左下)では、まずアプリケーションのOpenTelemetryの定める形式と方法でテレメトリーデータを収集するための処理を入れる必要があります。多くの場合、ライブラリを参照しコードを追加する必要があるのですが、このことを「Instrumentation(計装=測を実する)」とよんでいます。この部分は、アプリケーションが実装された言語・ランタイムによって最適な方法が異なります。そのためOpenTelemetryプロジェクトでは対応する言語ごとに必要なツールやライブラリを実装しています。また、必要最小限のコードで計装できるようになる自動計装(automatic instrumentation)と、細かい挙動まで実装者が制御できる手動計装(manual instrumentation)が用意されています。いずれかの方法あるいは両方の方法で計装を行います。

opentelemetry.io

計装したことでテレメトリーデータを集められるようになったあとは、バックエンドにデータを送信する必要があり、これを「コレクター(Collector)」と呼んでいます。一番単純な方法としては、アプリケーションで計装したものを直接エクスポーターで送信する仕組みが考えられます。これは図の左下のCollector(Agent方式)が直接バックエンドに送信することを意味します。加えて、アプリケーションで計装したテレメトリーデータをフィルタリングしたり、加工したりすることもできます。アプリケーションプロセスが大量にあるので注目したいデータのみに特化する場合や、ホスト名といった環境情報を付加する場合などです。これは図の中央のCollector(Standalone)に相当し、その中でデータを受信する「レシーバー(receiver)」、加工する「プロセッサー(processor)」、送信するエクスポーターの3つのコンポーネントから構成されます。

opentelemetry.io

計装は言語ごとに用意されていますが、その形式は標準化されているため、コレクターはアプリケーションの言語を問わず利用できます。またJaegarなどの既存のツールを利用している場合、ツールが出力するテレメトリーデータをOpenTelemetry形式に解釈するアダプターとなるレシーバーを介することでOpenTelemetryのコレクターに取り込むことが可能になっています。

f:id:tanaka733:20220106001325p:plain

OpenTelemetryのステータスとOpenTelemetry .NET

OpenTelemetryプロジェクトのステータスはここで公開されています。

opentelemetry.io

メトリクスとトレースの仕様については安定(Stable)となっています。ロギングについてはドラフト状態ですが、メトリクスやトレースと比べてログは既存のログライブラリが多数存在し、いかにそれらとつなぎこむかの設計に時間がかかっているのではないかと想像しています。

また言語ごとに用意されている計装についてはこちらに一覧があります。

github.com

念の為最新の状況は言語ごとのリポジトリで確認しましょう。OpenTelemetry .NETはこちらです。

github.com

これを見ると、TraceとExporterに関しては .NETはかなり対応が進んでいます。Metricsについても対応が進みつつあります

次回以降、実際にOpenTelemetry .NETを使う方法を説明します。なお、バックエンドにはNew Relicを使いますが、その理由はOpenTelemetryネイティブのOpenTelemetry Protocol (OTLP)フォーマットでデータ送信できるという点と、私が一番詳しくしっているバックエンドだからです。