OpenTelemetryとElasticを使用した3つのロギングモデル

log_infrastructure_apm_synthetics-monitoring.jpeg

おそらく、OpenTelemetryは、開発者によるトレースとメトリックの活用を(大幅に)促進しています。しかし、ロギングも引き続き、柔軟でアプリケーション固有のイベントドリブンデータを入手する際に重要な役割を担うでしょう。しかも、OpenTelemetryは既存のアプリケーションロギングフローに付加価値をもたらす可能性があります。

  1. コンテクスト間の相関付けを容易にする、トレース、メトリック、ロギングに共通のメタデータ。これにはRESTまたはRPC APIの一部としてサービス間で渡されるメタデータが含まれます。これは水平方向にスケールされる分散型システムが一般的な昨今において、サービスのオブザーバビリティの重要な要素となります。

  2. トレース、メトリック、ロギング用の任意の統合データパス。ツールの共通化と、オブザーバビリティバックエンドへのシグナルルーティングが容易になります。

これまで、開発者によるメトリックとトレースの導入は比較的小規模でした。さらに、独自ベンダーや独自APIの数は(導入率と比較して)比較的多い状況です。そのため、OpenTelemetryは、ベンダーに依存しない新たなトレースおよびメトリック用のAPIを開発するという未開拓分野へのアプローチを採用しました。対照的に、ほとんどの開発者がサービスのログをほぼ100%取得しています。さらに、ロギングはベンダーに依存しない少数のオープンソースロギングライブラリと関連APIの大半でサポートされています(LogbackILoggerなど)。このような状況があるため、OpenTelemetryのロギングへのアプローチは、既存の一般的なロギングフレームワークへのフックをすでに使用している開発者に適しています。こうして、開発者はコードや、オブザーバビリティシグナルとしてのロギングへの投資を変更することなく、OpenTelemetryをログシグナル出力として追加できます。

特にロギングは、OTelによってサポートされているオブザーバビリティシグナルの中では最も成熟度が低いものです。サービスの言語や、貴社の挑戦意欲にもよりますが、サービスやアプリケーションからログをエクスポートし、オブザーバビリティバックエンドでそれらを結合する際の選択肢はいくつかあります。

この記事の目的は、現在の最先端のOpenTelemetryのロギングについて確認し、次の各領域を念頭に置いて利用可能なアプローチに関するガイダンスを提供することです。

  • サービスログとOTelによって生成されたトレースとの相関関係(該当する場合)
  • 例外の適切なキャプチャ
  • トレース、メトリック、ロギングに共通するコンテクスト
  • slf4jキーバリューペアのサポート("構造化ロギング")
  • OTelのバゲージを通じてサービス間で伝送されるメタデータの自動添付
  • Elastic®オブザーバビリティのバックエンドの使用
  • 採用されたアプローチに依存しない、Elasticの一貫したデータ精度

OpenTelemetryのロギングモデル

アプリケーションまたはサービスのログをOTelのトレースおよびバゲージと関連付けてElasticに取得する方法のモデルは、現在3つ存在します。

  1. 埋め込みのOpenTelemetry Instrumentationライブラリを使用して、OTLPプロトコルを介してサービスからログを(トレースおよびメトリックとともに)Elasticに出力

  2. OpenTelemetry Collectorによってスクレイピングされたサービスからファイルにログを書き込み、OTLPプロトコルを介してElasticに転送

  3. Elastic Agent(またはFilebeatによってスクレイピングされたサービスからファイルにログを書き込み、Elasticによって定義されたプロトコルを介してElasticに転送

(2)や(3)とは異なり、(1)ではElasticへの取り込み前にサービスログをファイルに書き込む必要がないことに注意してください。

ロギングとスパンイベントの比較

OpenTelemetryを含むほとんどのAPMシステムがスパンイベントも想定していることは注目に値します。ログのステートメントと同様に、スパンイベントには任意のテキストデータが含まれます。また、スパンイベントは、親スパンに適用されたカスタム属性("ユーザーID"など)を自動的に保持するので、相関付けやコンテクスト付けに役立ちます。このため、一部の既存の(スパン内の)ログステートメントをスパンイベントに変換すると便利な場合があります。もちろん、名前のとおりスパンイベントはスパン内からしか送信できないため、ロギングの汎用的な代替機能として存在しているわけではありません。

ロギングとは異なり、スパンイベントは既存のロギングフレームワークを通過しないため、(実際に)ログファイルに書き込むことはできません。また、スパンイベントは技術的にはトレースデータの一部として送信され、他のトレースデータと同じデータパスとシグナルルーティングをたどります。

Polyfillアペンダー

一部のデモでは、(2)と(3)のモデル向けにカスタムLogback "Polyfillアペンダー"(OTelのLogback MDCに着想を得ています)を使用して、ログメッセージへのslf4jキーバリューペアの添付をサポートしています。

Elastic Common Schema

Elastic内のログメッセージが完全な精度を示すようにするには、Elastic Common Schema(ECS)に従ってフォーマット化を進める必要があります。モデル(1)と(2)では、ログメッセージはElastic APMサーバーによってインジェストされるまで、OTelログセマンティクスでフォーマットされたままになります。次に、Elastic APMサーバーでOTelログセマンティクスがECSに変換されます。モデル(3)では、ソースでECSが適用されます。

注目すべきは、OpenTelemetryが最近、Elastic Common Schemaを今後のセマンティック規則の標準として導入したことです。このため、現在のOTelログセマンティクスはECSに合わせて更新されるものと予想されます。

使いはじめる

ここに含まれるデモは、"POJO"(想定フレームワークなし)Javaプロジェクトを中心に据えています。Javaはおそらく、OTelでサポートされている言語の中でも、特にロギングオプションに関して最も成熟している言語です。特に、このJavaプロジェクトは、ここで議論されている3つのロギングモデルをサポートできるように設計されています。実際にはこれらのモデル(および対応するプロジェクトの依存関係)のうち、1つだけを実装します。

このデモは、Docker環境とElastic Cloudインスタンスが利用可能であることを前提としています。

1.git clone https://github.com/ty-elastic/otel-logging

2.次の(適切に入力された)環境変数を使用して、otel-loggingのルートに.envファイルを作成します。

# the service name
OTEL_SERVICE_NAME=app4

# Filebeat vars
ELASTIC_CLOUD_ID=(see https://www.elastic.co/guide/en/beats/metricbeat/current/configure-cloud-id.html)
ELASTIC_CLOUD_AUTH=(see https://www.elastic.co/guide/en/beats/metricbeat/current/configure-cloud-id.html)

# apm vars
ELASTIC_APM_SERVER_ENDPOINT=(address of your Elastic Cloud APM server... i.e., https://xyz123.apm.us-central1.gcp.cloud.es.io:443)
ELASTIC_APM_SERVER_SECRET=(see https://www.elastic.co/guide/en/apm/guide/current/secret-token.html)

3.目的のモデルを使用してデモを起動します。

  • OTel APMエージェントを介してロギングをデモしたい場合は、次を実行します:MODE=apm docker-compose up
  • OTel filelogreceiverを介してロギングをデモしたい場合は、次を実行します:MODE=filelogreceiver docker-compose up
  • Elastic Filebeatを介してロギングをデモしたい場合は、次を実行します:MODE=filebeat docker-compose up

4.お使いのElastic Cloudインスタンス内の受信スパンと相関ログデータを検証します。

モデル1:OpenTelemetryのインストルメンテーションによるロギング

このモデルは、OpenTelemetryの長期的な目標、つまりサービスからのトレース、メトリック、ロギング(共通の属性を含む)OpenTelemetry Instrumentationライブラリを通じてログファイルやスクラッパーに依存せずに統合することに適しています。

このモデルのサービスでは、一般的なロギングライブラリ(Logback for Javaなど)を使用して、今までと同様にログステートメントを生成します。OTelは、OTelのLogback Appenderを介してLogbackに"サウスバウンドフック"を提供します。これにより、ServiceName、SpanID、TraceID、slf4jキーバリューペア、OTelバゲージがログ記録に挿入され、構成された記録は共存するOpenTelemetry Instrumentationライブラリに渡されます。さらに、カスタムLogRecordProcessorを使用して、ログ記録にバゲージを属性として追加します。

次に、Otel InstrumentationライブラリはOTelのロギングの仕様に従ってログステートメントをフォーマットし、OTLP経由でOTel Collectorに送信してルーティングとエンリッチメントを強化するか、Elasticに直接送信します。

なお、言語サポートが充実するにつれて、このモデルは、利用可能な場合は自動インストルメンテーションを備えたランタイムエージェントバインディングによってサポートされる可能性があります(たとえば、ランタイム言語にコード変更は不要)。

このモデルの目立った利点は、ただシンプルなだけでなく、属性とトレースのメタデータをログステートメントと直接、簡単に結び付けられることです。これにより、OTelによってサポートされているその他のオブザーバビリティシグナルのコンテクストでは、さらにロギングが便利になります。

アーキテクチャー

モデル1のアーキテクチャー

明示的には示されていないものの、OpenTelemetry CollectorをサービスとElasticの間に挿入することで、追加のエンリッチメントや、オブザーバビリティバックエンド間でのシグナルルーティングや複製を容易にできます。

メリット

  • シグナルのアーキテクチャーが簡素化され、"可動部分"が減少(ファイル、ディスク使用率、ファイルローテーションの懸念が不要)
  • OTelの長期的なビジョンと一致する
  • ログステートメントをOTelのメタデータによって(簡単に)修飾できる
  • ポリフィルアダプターなしでslf4jによる構造化ロギングをサポート
  • 追加のコレクターやエージェントが不要
  • ECSへの変換がElastic内で行われるため、インジェストされるまでベンダーに依存しないログデータを保持
  • トレース、メトリック、ログに共通のワイヤーラインプロトコル(OTLP)

デメリット

  • OTelのサポート言語の多くで(まだ)利用できない
  • アドホックなオンノードデバッグ用の中間ログファイルがない
  • 未成熟である(アルファ版/実験段階)
未知の"グレア"状態の存在。サービスが途中で終了した場合またはバックエンドが長期間ログデータを認識できなかった場合、ログデータが失われる可能性がある

デモ

MODE=apm docker-compose up

モデル2:OpenTelemetry Collectorを介したロギング

モデル1のデメリットを考慮すると、サービスとオブザーバビリティバックエンドの間を引き続き実際のログファイルで仲介するモデルを検討する方が便利かもしれません。このようなモデルを実現するには、OpenTelemetry Collectorをサービスと併存させ(同じホスト上になど)、filelogreceiverを実行してサービスのログファイルをスクレイピングします。

このモデルのサービスでは、一般的なロギングライブラリ(Logback for Javaなど)を使用して、今までと同様にログステートメントを生成します。OTelはMDC Appender for Logback(Logback MDC)を提供しており、これを使用することでSpanID、TraceID、バゲージをLogback MDCのコンテクストに追加できます。

特にOTel filelogreceiverではログ記録の構造は想定されていません。今回の例では、logstash-logback-encoderを使用してログメッセージをJSONにエンコードします。logstash-logback-encoderはMDCコンテクストからOTelのSpanID、TraceID、バゲージを読み取り、JSON構造へとエンコードします。特にlogstash-logback-encoderは、slf4jキーバリューペアを明示的にはサポートしていません。しかし、Logback構造化引数はサポートしているため、ここではPolyfill Appenderを使用してslf4jキーバリューペアをLogback構造化引数に変換します。

そこから、ログ行をログファイルに書き込みます。環境内でKubernetesまたはその他のコンテナーオーケストレーションを使用している場合は、通常はstdout(コンソール)に書き込み、オーケストレーションのログドライバーにログファイルへの書き込みと管理を許可します。

次に、OTel Collectorでこのログファイルを(filelogreceiverを使用して)収集できるように設定します。ログ行の形式が何も想定されていないため、ログスキーマからOTelログスキーマにフィールドを明示的にマップする必要があります。

そこから、OTel Collectorはフォーマットされたログ行をバッチ処理し、OTLPを介してElasticに送信します。

アーキテクチャー

モデル2のアーキテクチャー

メリット

  • デバッグが簡単(中間ログファイルを手動で読み取ることが可能)
  • 固有のファイルベースのFIFOバッファー
  • サービスが途中で終了した場合でも"グレア"状態になりにくい
  • ECSへの変換がElastic内で行われるため、インジェストされるまでベンダーに依存しないログデータを保持
  • トレース、メトリック、ログに共通のワイヤーラインプロトコル(OTLP)

デメリット

  • ファイルベースのロギングの問題点が残る(ローテーション、ディスクのオーバーフロー)
  • ベータ版品質であり、現場での活用実績がない
  • slf4jキーバリューペアがサポートされない

デモ

MODE=filelogreceiver docker-compose up

モデル3:Elastic Agent(またはFilebeat)を介したロギング

先ほど説明した2つ目のモデルはバックアップファイルとしてある程度の回復力を提供しますが、依然としてOTel Collector filelogreceiverモジュールは明らかに"ベータ版"品質です。Elasticにログをインポートする際は、デバッグツールとしてのログの重要性を考慮して、通常は現場での使用実績のあるElastic AgentFilebeatのスクラッパーを引き続き使用するのがお勧めです。Elastic AgentとFilebeatには、この分野で長年にわたり現場で使用されてきた実績があり、成熟しています。さらに、OpenTelemetry以外のさまざまなシグナルを取り込む際も、Elastic Agentをデプロイすると便利な場合が多くあります(ディープKubernetes、ホストメトリック、セキュリティーなど)。

このモデルのサービスでは、一般的なロギングライブラリ(Logback for Javaなど)を使用して、今までと同様にログステートメントを生成します。モデル2と同様、OTelのLogback MDCを使用して、SpanID、TraceID、バゲージをLogback MDCのコンテクストに追加します。

そこから、Elastic ECS Encoderを使用して、Elastic Common Schemaに準拠したログステートメントをエンコードします。Elastic ECS EncoderはMDCコンテクストからOTelのSpanID、TraceID、バゲージを読み取り、JSON構造へとエンコードします。モデル2と同様に、Elastic ECS Encoderではslf4jキーバリューペア引数がサポートされていません。不思議なことに、Elastic ECS EncoderではLogback構造化引数もサポートされていないようです。そこで私は、Polyfill Appender内ではMDCコンテクストとしてslf4jキーバリューペアを追加することにしています。しかしこれは理想的とは言えません。MDCではすべての値が文字列にされてしまうからです。

そこから、ログ行をログファイルに書き込みます。環境内でKubernetesまたはその他のコンテナーオーケストレーションを使用している場合は、通常はstdout(コンソール)に書き込み、オーケストレーションのログドライバーにログファイルへの書き込みと管理を許可します。次に、ログファイルを収集するようにElastic AgentまたはFilebeatを設定します。現在、特にElastic ECS Encoderでは、MDC上で受信したOTel SpanID変数とTraceID変数が変換されません。したがって、Filebeat(またはElastic Agent)の設定から、これらの変数を手動で調整し、同等のECSにマッピングできるようにする必要があります。

アーキテクチャー

モデル3のアーキテクチャー

メリット

  • 堅牢かつ現場での実績あり
  • デバッグが簡単(中間ログファイルを手動で読み取ることが可能)
  • 固有のファイルベースのFIFOバッファー
  • サービスが途中で終了した場合でも"グレア"状態になりにくい
  • Elasticで簡単に操作できるネイティブECS形式
  • Elastic Agentを介してFleet管理

デメリット

  • ファイルベースのロギングの問題点が残る(ローテーション、ディスクのオーバーフロー)
  • slf4jキーバリューペアまたはLogback構造化引数がサポートされない
  • Filebeat設定でOTelのSpanIDとTraceIDの変換が必要
  • ログのデータパスと、トレースおよびメトリックのデータパスが異なる
  • ベンダー固有のロギング形式

デモ

MODE=filebeat docker-compose up

推奨事項

現在、ほとんどのお客様にお勧めしているのがモデル3です。つまり、ECS形式で(OTelのSpanID、TraceID、バゲージのメタデータとともに)ログに書き込み、アプリケーションまたはサービスをホストしているノードにインストールされたElastic Agentを使用してログを収集します。現在のElastic Agent(またはFilebeat)は、OpenTelemetryのコンテクストでアプリケーションやサービスからログファイルをキャプチャするにあたり、トップクラスに現場での使用実績が豊富で確かな手段です。

さらに、同じElastic Agentインスタンス(理想的には、お使いのKubernetes DaemonSet内で実行されているもの)を利用して、豊富でかつ堅牢なメトリックとログを、Kubernetesやその他の多くのサポート対象サービスからElastic統合機能群を介して収集できます。最後に、Elastic AgentはFleetを介したリモート管理が容易であるため、設定ファイルの複雑化を回避できます。

ノードをベンダーニュートラルに保つか、シグナルルーティングシステムを統合することを目指すお客様には、OpenTelemetryのコレクターを使用してサービスログファイルを収集するモデル2がお勧めです。現在、一部の初期導入者によって利用されてはいますが、OpenTelemetry filelogreceiverが現在もベータ版品質であることを考慮すると、どうしてもある程度のリスクは伴います。

モデル1は広くお勧めすることはできません。言語サポートが限定的であるうえ、実験/アルファ版の段階であり(APIは変更される可能性がありますが)、データ損失の可能性もあるためです。とはいえ、いずれ言語サポートが充実し、設計上の回復力も考慮されれば、メタデータの単純さと豊富さの両面が明らかなメリットとなるでしょう。

ログからさらに多くの価値を引き出す

トレースやメトリックとは対照的に、ほとんどの組織がアプリケーションやサービスのログをほぼ100%取得しています。これは、アプリケーションのオブザーバビリティシステムを構築するための入口としては申し分ありません。一方で、ログは非常にノイズが多く、構造化されていないことが多いと言われています。この問題はハイパースケーラーやKubernetesが実現したスケーリングによって増幅されています。ログ行を確実に収集するだけなら簡単ですが、今日の企業の規模で活用しようとするのは困難です。

ロギングはおそらく、オブザーバビリティシグナルとして大きな価値を得るのが最も難しい手法であるため、理想を言えば他のオブザーバビリティシグナルを想定したロギングへのベンダーサポートのことも慎重に検討するべきでしょう。予期せぬスケーリングや、エラー、テストシナリオでのログレートの急増に対応できるでしょうか?ログ行のパターンを自動的に認識し、カテゴリー別に分類して、異常の真相を特定できるように設定された機械学習ツールはあるでしょうか?手動によるリハイドレーションが不要で、コスト効率にも優れたログのオンライン検索機能を、数か月または数年にわたり提供してくれるでしょうか?ログに潜むビジネスKPIを抽出して分析するためのツールは提供されていますか?

OpenTelemetryを初期から熱心にサポートしているElasticなら、もちろんOTelのトレース、メトリック、ログをネイティブにインジェストできます。そして、Elasticのシステムが受信するすべてのログと同様に、OTelを使用したソースが受信するログも、Elasticの成熟したツールと次世代AI Opsテクノロジーで利用することができるため、ログの価値を最大限に引き出すことができます。ご興味を持たれた場合は、Elasticのプリセールスチームにお問い合わせください。Elasticを利用した開発を始めましょう。

本記事に記述されているあらゆる機能ないし性能のリリースおよびタイミングは、Elasticの単独裁量に委ねられます。現時点で提供されていないあらゆる機能ないし性能は、すみやかに提供されない可能性、または一切の提供が行われない可能性があります。