入門OpenTelemetryを読んで学んだこと

忘れないために書いていきます。

# 文献や資料について
https://www.oreilly.co.jp/books/9784814401024/

https://opentelemetry.io/ja/

# 前提となるオブザーバビリティとは？
一言でまとめるのは難しいですが、オブザーバビリティとは
**システムの内部状態を外部から観測可能にする**こと、その能力を指しています。
それによって、障害発生時の原因の特定やパフォーマンスの最適化を行うことができるように
なります。

## 従来の考え方と注目されている背景について
これまではモニタリングをすることで監視を行っていました。
モニタリングでやっていたことは以下のようなことだったと思います。
1. CPU/メモリなどのリソース状況の監視
1. リクエストの成功率など
1. 監視対象が閾値を超えた場合のアラートなど

ただこれらのモニタリングは様々な課題がありました。
### モニタリングの課題
1. 事前定義した指標でしか監視できない
    - 未知の障害や想定外の事象に対応しづらい
1. 根本原因の特定が難しい
    - エラーが発生しても、背景にあるリクエストや問題が見えづらい
1. 分散システムへの対応に弱い
    - マイクロサービスが複数絡むようなアプリケーションだと単純なメトリクスだと追跡が難しい

個人的には3の問題が近代オブザーバビリティが注目されている大きなポイントとも言えるのかなと思いました。

オブザーバビリティは上記課題に対してアプローチが可能です。

### オブザーバビリティのアプローチ
1. 事前定義された指標しか監視できない
    - 詳細なログやトレースを組み合わせて検知可能
    - 特定のクエリやトランザクションの遅延をリアルタイムで検知できたりなど
1. 根本原因の特定が難しい
    - トレースの情報を活用してどのコンポーネントにどのくらいの時間がかっているかなどを観測できる
1. 分散システムへの対応に弱い
    - マイクロサービス間のトレースやログ等を統合的に収集可能
    - リクエストが各コンポーネントでどのように動いてるかなど計測できる

オブザーバビリティでは上記を体現するために、**テレメトリー**を収集します。
**テレメトリー**とはシステムが何をしてるかを示すデータを指します。
テレメトリーを構築するのは、ログ・メトリクス・トレースなどの情報です。
収集されたテレメトリーとそのテレメトリーを使って分析すること、
**分析とテレメトリーを合わせたものをオブザーバビリティ**と呼びます。

そのオブザーバビリティを実現するテレメトリーシステムこそが
OpenTelemetryであるということです。

# OpenTelemetryのメリット
## ユニバーサルスタンダード
Datadogや他のモニタリングのサービスを固有で使用しないため、
ベンダーのロックインを排除することができます。
モニタリングのサービスを変更することになっても柔軟に変更ができます。
また主要なクラウドプロバイダーもサポートを行なっており、標準化に向けて動いています。

## 相関されたデータ
すべてのテレメトリーは同じ場所に放り込まれた山ではなく、
すべての情報は同じデータの断片であり、時系列でシステム全体を記述するグラフに
相関されます。
（例えば、障害発生時に関連するトレースを即座に確認できるなど）

例で挙げたDatadogなどでも近しい使用はできる部分もあると思いますが、
**自動で相関を構築**することは難しいです。

# OpenTelemetryを構成するもの
## 主要なシグナルについて
### トレース
リクエストがシステム内をどのように流れたかを時系列で記録する
ログの集合体を指します。
また、そのログをスパンと表現します。
つまりトレースとはスパンの集合と言えます。

またトレースの特徴として、メトリクスやログなどの他のシグナルへの変換も可能です。
```shell
http_request_duration_seconds{method="GET", path="/hoge"}  123.3 (平均)
```

#### スパンが持つもの
作業や操作の単位を表すものです。
スパンは以下のような情報を持ちます。
| キー | 値 |
| ---- | ---- |
| http.request.method | "GET" |
| url.path | "/hoge/id/1" |
| http.response.status_code | 200 |

リクエストされた様々な情報を持つものだと認識しています。

### メトリクスについて
CPU使用率やエラー発生率のようなインフラやアプリケーションの一定期間に集計されたものを
指します。
それらはメトリクスの一般的な意味合いと同義だと思います。
OpenTelemetryでは以下の主要な目的をサポートするように設計されているそうです。
1. コード内で重要かつ、セマンティクス的に意味のあるイベントを定義、それらのイベントがどのようにメトリクスシグナルに変換されるかを指定できるようにすべき（開発者）
2. メトリクスの時間または属性を集約（または再集約）することでコスト・データ量、解像度を制御できるべき（運用者）
3. 変換は測定値の本質的な意味を変えてはならない

※セマンティクス＝意味論。プログラムやデータやイベントが持つ「意味」を明確にすること

つまり、メトリクスの値は単なる数値というわけではなく、アプリケーションの文脈に応じた
**意味のある情報**として設計するべきと理解しました。

### ログ
ログとは構造化（また非構造化）されたメタデータを含むタイムスタンプ付きのテキストレコードのことを指します。
1. レガシーコード、メインフレーム、その他の記録システムなど、その他トレースできないサービスからシグナルを取り出す
2. マネージドデータベースやロードバランサーなどのインフラストラクチャリソースをアプリケーションイベントと関連づける
3. cronジョブやその他の反復的でオンデマンドな作業など、ユーザーのリクエストと結びつかないシステムの動作を理解する
4. メトリクスやトレースなどの、他のシグナルに加工する

なるほど、トレースはユーザーのアクション（リクエスト）に基づいた計測だったが、
cronのジョブなどユーザーのアクション以外の情報も収集ができるものがOpenTelementryの文脈で言うところのログに当たると言うことだと理解しました。
またログはトレースやメトリクスへの変換も可能であると。

### コンテキスト
トレースやスパンの情報を伝播するものです。
Baggageというものを使って追加のメタ情報を載せて送ることができます。例えば以下のようなものです。
```shell
baggage: user_id=12345, region=us-west, request_priority=high
```
誰が、どこで、優先度は、という情報を付与してトレースを伝播できるものです。
コンテキストの電波仕様はW3C Trace Contextにも記載されています。
https://www.w3.org/TR/trace-context/

### セマンティック規約
ログ・メトリクス・トレースのデータに統一された意味（セマンティック）を持たせるべきルールのことを指します。
共通の設計にすることで、確かにシステム内で扱いやすくなるだろうと思いました。
本の中では、サードパーティのライブラリやフレームワークもオブザーバビリティを持ってリリースすることができると記載されていました。
共通の設計になることは間違いなく価値があるとは思いますし、様々なコンポーネントに対しても
定義されているため軽装を組み込むのもやりやすい？（迷わない）みたいなメリットがあるのかなと思いました。

### テレメトリーパイプライン
各シグナル（ログ・トレース・メトリクス）を収集して、処理して転送する仕組みのことを指します。
（Datadogなどのサービスに転送する）
OpenTelemetryには主要なコンポーネントとして、**OpenTelemetry Collector**と
**OpenTelemetry Protocol**が存在します。
TODO：この二つは後で触れそう

### OpenTelemetry Collector
ざっくりなイメージですが、アプリケーションからメトリクスサービスへの中継サーバのような
理解をしました。
受信したものを加工したりもできるものと理解。

# 最後に
全箇所触れるととてつもない量になるので、ここまでとします。
本ではデモを用いた説明があったりインフラ（k8sなど）を絡めた説明などがありました。

ちゃんとまとめたいですが、実際に構築しながら学んでいく方が良さそうなので
気が向いたらまとめます。