可観測性とOpenTelemetryの紹介

# はじめに
この記事は、[NTTテクノクロス Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ntt-tx)の7日目の記事です。

こんにちは。NTTテクノクロスの小久保 ( @kokubo_yuichi ) です。

普段は、[ビッグデータ・AI・IoT](https://www.ntt-tx.co.jp/products/service/bigdata_ai_iot.html?utm_source=qiita&utm_medium=ac2019&utm_campaign=07)を扱う部署に所属しており、最近では、センサを利用して取得した生体データをニアリアルタイムに分析する基盤や、コンテナアプリケーションを配信する基盤、分散した異種データソースを横断検索する基盤等の開発を行ってきました。開発にはOSSを利用することが多く、ここ数年ではCloud Foundry、Apache Hadoop、Apache Spark、Apache Kafka、Kubernetes、Apache Drill等を利用した開発を行っています。
最近は、APMの分野に興味があるので、今日はパフォーマンスモニタリングに繋がる話として「可観測性」と「OpenTelemetry」について紹介していきたいと思います。

# 可観測性（Observability）とは
可観測性とは、運用していく上で必要な情報がシステムから取得可能な状態になっていることを指しています。
また、取得した情報はテレメトリデータとして送信し、運用監視ツールで可視化したり、コンテナ配置のオーケストレーションに利用したり、運用の様々な場面で利用することができます。

「可観測性」というキーワードが登場した背景には、以下のような状況があると考えています。

クラウドネイティブにスケーラビリティや耐障害性を考えてシステムを構築すると、機能毎の小さな役割に分割しないと扱いづらいためマイクロサービス化が必要になります。システムの構成要素をマイクロサービスにすれば、分散配置や協調動作も機能毎に容易にできるようになり、システムの負荷に応じてスケールアウトさせたり、ディザスタリカバリ対策として複数リージョンで動作させたり柔軟な運用を行うことができます。

しかし、マイクロサービス化することが全て良いことばかりとは限りません。

オンプレミスに構築されたモノリシックなシステムでは、何がどこで動いているのか分かりやすかったので、システムの状態を外からモニタリングすることが比較的簡単に行えました。しかし、マイクロサービス化されたシステムでは、システムとして柔軟性が高くなる反面、複数のマイクロサービスが連携して動作することにより、システム全体の複雑度が上がることになります。
そして、マイクロサービスがどこで動いて、どのように連携しているのか、問題は起こっていないかといった、システムの状態を外からモニタリングすることが難しい状況が生まれました。

システムのアーキテクチャスタイルが変わることによって、外からシステムをモニタリングしていた今までの「監視」で状態を把握することが難しくなり、マイクロサービス化された複雑なシステムのモニタリングを行おうとした結果、システムやアプリケーション側からテレメトリデータを能動的に提供する「可観測性」の必要性が高まったのだと考えています。

また、分散されたマイクロサービスで取得した情報を個々に眺めてもあまり良い情報は得られないので、システムやアプリケーション側からテレメトリデータとして発信し、運用監視ツール等で集約して利用する必要があります。テレメトリデータの発信にはエージェントの常駐が必要になることが多いですが、今まではコンピュータ性能の限界もあり、モニタリングに多くのリソースが割けないという状況がありました。更に、システムを正確にモニタリングするには高頻度にテレメトリデータを送信することも必要になり、ネットワークのトラフィック増加も大きなネックとなっていました。
しかし、コンピュータやネットワークの性能が向上したことで、CPUやメモリといったリソースや、ネットワーク帯域や速度といった可観測性を実現するためのリソースが十分利用可能な状況になり、比較的エージェントの常駐に対するハードルが下がったということも背景としてあると思っています。

# 可観測性を確保するためのテレメトリデータ
可観測性を確保するためには、大きくは以下の3つの情報をテレメトリデータとして、システム側から能動的に提供する必要があります。

* 分散トレーシング
* メトリクス
* ログ

分散トレーシングは、論理的なひとつの操作に対する、プロセスやネットワーク、セキュリティ境界を越えたイベントの呼び出し関係のセットです。クライアントからのリクエストが実行される流れを辿り、どの処理がどの順番で行われているのか、どこでどのぐらい時間が掛かったのかというような情報を知ることができます。主に、パフォーマンスが低下している処理や、問題が起こっている処理を把握するのに役立ちます。プログラムで言うところのコールスタックをイメージすれば分かり易いと思います。

メトリクスは、システム内のリソースに関する測定値や、測定値を集約した指標値です。例えば、CPUやメモリの使用量といったゲージ値であったり、アクセス数といったカウンタ値がメトリクスに該当し、記録したタイミングでシステムのリソースがどのような状態だったかを知ることができます。主に、リソースを過剰利用している処理の把握や、メトリクスのトレンドから今後のシステム利用予測をするのに役立ちます。

ログは、システムの動作状況や情報を記録したものです。アクセスログのようにシステムの証跡や、エラーログのように問題が発生した時の状況をタイムスタンプと関連付けてイベントとして記録します。主に、問題が発生した際の原因解析に役立ちます。出力形態としては、単にフィールドとして値が列挙され、ログを見ただけではぱっと見何の値かが分かりにくい非構造化ログと、JSONのようにキーと値の形式でフィールドを出力し、一目で何の値かが分かり易い構造化ログがあります。後でログから機械的に情報を抽出したり、別用途で活用したいと考えるなら、構造化ログとして出力しておくことをお勧めします。

マイクロサービスのレベルでのトレーシングやロギングは、アプリケーションに手を入れずにサイドカーで入出力やログ出力をインターセプトして分散トレースしたり、監視ツールに集約することができます。
アプリケーションの処理レベルでのトレーシングやロギングもすることができます。アプリケーション内でロギングするためのコード埋め込みは良く行われていると思いますが、処理レベルでのトレーシングをする場合は、開発言語にもよりますが、トレーシングのためのライブラリをインポートしたり、コード埋め込みが必要になることもあります。

いずれにしても、マイクロサービス化されたシステムを正しく運用していくためには、今まで以上にシステムを設計する段階から、どのような情報をテレメトリデータとして収集するのか、モニタリングするのかといったことを意識して設計する必要があると考えています。

# テレメトリデータの収集
CNCFでは、クラウドネイティブなシステムにするためにはどのようなツールや技術を選択するべきなのかということを、[Cloud Native Trail Map](https://github.com/cncf/trailmap)として公開しています。その中で、可観測性ツールとしては、それぞれのテレメトリデータに対して、分散トレーシングにはJaegerやJaegerのようなOpenTracing準拠の実装、メトリクスにはPrometheus、ログ収集にはFluentdが選択肢として挙げられています。

> 4 OBSERVABILITY & ANALYSIS
> • Pick solutions for monitoring, logging and tracing
> • Consider CNCF projects Prometheus for monitoring, Fluentd for logging and Jaeger for Tracing
> • For tracing, look for an OpenTracing-compatible implementation like Jaeger

引用元：Cloud Native Trail Map ( https://github.com/cncf/trailmap )

また、クラウドネイティブなツールやサービスの一覧として[Cloud Native Landscape](https://landscape.cncf.io/)もあり、その中でも「Observability and Analysis - Monitoring」には53ものツールやサービスが挙げられています。

更に、CNCFで挙げられているツール以外にも、Googleが社内利用していた分散トレーシングとメトリクスのツール類をオープンソース化した[OpenCensus](https://opencensus.io/)もあり、何を基準にして選択したら良いのか、判断に困ることと思います。

そんな中、今一番注目しているのは、ここで挙げたCNCFのincubating projectの一つで分散トレーシングを扱う「OpenTracing」と、競合関係にあった「OpenCensus」を統合して爆誕した「[OpenTelemetry](https://opentelemetry.io/)」というプロジェクトです。

# OpenTelemetry
OpenTelemetryには、分散トレーシング、メトリクス、コレクタといった、可観測性を確保するために必要なテレメトリデータを収集する機能が用意されています。
OpenTelemetryは、中立的な立場でベンダロックインされていないので、OpenTelemetryを利用してテレメトリデータを収集できるようにしておけば、可視化や分析に様々なツールが選択できる（ようになるはず）というのも魅力です。更に、OpenTelemetryでは、2年間バックワードコンパチビリティを維持することも発表していますので、OpenTracingやOpenCensusを既に利用している人も比較的移行しやすいのではないかと思います。
OpenTelemetryとしての統合は、今年発表されたばかりで、プロジェクトもまだAlpha2（2019/12/3現在）の段階ですが、今後は、「OpenTelemetry」が「可観測性」を確保するためのテレメトリデータの収集ツールとして重要な選択肢の一つになると考えていますので、引き続き注目していこうと思います。

# おわりに
今日は、クラウドネイティブなモニタリング界隈でバズっている「可観測性」という言葉と、それを実現するために「OpenTelemetry」というプロジェクトができたよという簡単な紹介をしました。
これだけでは、OpenTelemetryを使うと何ができるの、どう使えばいいのということについてわからないと思いますので、今後はOpenTelemetoryを実際に触りながら「OpenTelemetryを動かしてみた」的な記事を上げて、紹介していくつもりです。ご期待ください。

それでは8日目は @U_ikki です。引き続き[NTTテクノクロス Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ntt-tx)をお楽しみください。