OpenTelemetry CollectorのProcessorを眺めてみる

OpenTelemetry Advent Calendar 2022、17日目の記事です

https://qiita.com/advent-calendar/2022/opentelemetry

# Processor

Processorとは、メトリクス、トレース、ログをバックエンドに送る際に様々な処理をかけられます、というものです。
とは言っても、何ができて、何を使ったらいいのかという疑問が湧いてくると思います。

そんな疑問に対して公式で[Recommended Processors](https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor#recommended-processors)が提案されています。
（下記は本記事作成時点の情報）

> **Traces**
> 1. memory_limiter
> 2. any sampling processors
> 3. Any processor relying on sending source from Context (e.g. k8sattributes)
> 4. batch
> 5. any other processors
> 
> **Metrics**
> 1. memory_limiter
> 2. Any processor relying on sending source from Context (e.g. k8sattributes)
> 3. batch
> 4. any other processors

これらが何なのかを見てみたいと思います。

## memory_limiter

- [Memory Limiter Processor](https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/memorylimiterprocessor)

Otel Collectorで使用するメモリに制限をかけるProcessorです。
ソフト制限とハード制限をかけられ、ソフト制限を超えるとデータのドロップを開始、ハード制限を超えるとデータドロップだけでなく強制的にガベージコレクションを実行します。
制限は固定値もしくはパーセントで指定できます。

これは問答無用で入れておいた方が良さそうですね。
なお、Processorをかける順番も大事です。特にデータドロップ系（Memory Limiterや次のサンプリング）は最初に実行する必要があります。


## any sampling processors

バックエンドや帯域の制約によってはサンプリング止む無しです。
サンプリングには二種類あります。

- [Probabilistic Sampling Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/probabilisticsamplerprocessor)

いわゆるHead-based samplingで、ランダムでサンプリングします。


- [Tail Sampling Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor)

ある程度Traceを蓄えた後、ポリシーに基づいてサンプリングします。
TraceのLatency、Status Code、Attribute、TraceState、Batch内のSpan数などに基づきサンプリングを行えます。
問題のないTraceは10%サンプリングし、Latencyが長かったり、エラーが発生したり、特定のAttributeを持つようなTraceを100%サンプリングするような使い方ができます。
Tail-basedの性質上Waitをかけるので（デフォルト30秒）、リアルタイム性であったりメモリ使用量に注意が必要ですね。

## Any processor relying on sending source from Context (e.g. k8sattributes)

Contextに基づく送信ソースに依存するProcessorとのことで、これが何を指しているかは具体的な情報はありません。
（色々なコンフィグのサンプルを見ても、memory_limiter、batchと来て他のProcessorが続くものが多いです。）
とりあえず例になっているk8sattributesを見てみます。

- [Kubernetes Attributes Processor (k8sattributes)](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/k8sattributesprocessor)

以下のKubernetesメタデータをデータに自動的にタグ付けできます。

k8s.namespace.name
k8s.pod.name
k8s.pod.uid
k8s.pod.start_time
k8s.deployment.name
k8s.node.name

こちらの記事に詳しく利用例が載っています。

https://opentelemetry.io/blog/2022/k8s-metadata/




## batch
- [Batch Processor](https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor)

データ圧縮効率化のためバッチ処理を行うProcessorです。
全てのコレクターにbatchを入れることが強く推奨されています。

バッチ送信タイミングは時間もしくはサイズで指定できます。
データドロップ系のProcessorを入れる場合は、memory_limiter　⇒　サンプリング　⇒　batch　の順番でPipelineを組んでね、とのこと。


## any other processors

Processorは[他にも色々](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor)あります。
ざっと概要を見てみます。


### Attribute処理系

- [Attribute Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/attributesprocessor)

Attributeに対して以下のような操作を行えます。

| 操作名 | 説明 |
|:-|:-|
|insert   | データに新しいAttributeを挿入。  |
| update  | Keyが存在するAttributeを更新。  |
| upsert  | Keyの有無によりinsertまたはupdateを実行。  |
| delete  |  対象Attributeを削除 |
| hash  | 既存のAttributeをハッシュ化(SHA1)。  |
| extract  |  対象Keyから正規表現ルールで抽出しtarget keyに設定。 |
|  convert | 既存のAttributeを指定された型に変換(int, double, string)。  |

対象AttributeのKeyは正規表現マッチもできます。
コンテキストのため任意のサービス名などを埋め込む、機密情報を削除やマスキングするなどの使い方ができますね。

- [Metrics Transform Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/metricstransformprocessor)
メトリクスの名前やラベルを変換したり、コピーして新しいメトリクス作ったり。

- [Redaction processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/redactionprocessor)
許可リスト、拒否リストを元にSpan属性（個人情報、機密情報など）を削除。

- [Resource Detection Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor)
Otelがインストールされているホストのリソース情報を検出しデータに追加。ホスト名、OSやEC2であればInstance Type、Regionなど。

- [Resource Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourceprocessor)
Resource Attributeの追加、変更。Resource Detection Processorで収集されない任意のAttributeを追加したり、書き換えたり。

- [Schema Transformer Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/schemaprocessor)
スキーマを変換。

- [Span Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/spanprocessor)
Span名変更、Span属性抽出、Spanステータス変更。

- [Transform Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/transformprocessor)
[OpenTelemetry Transformation Language](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/pkg/ottl)を用いた高度なAttribute処理（多分）。

### Value処理系

- [Cumulative to Delta Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/cumulativetodeltaprocessor)
累積値をデルタ値に変換。

- [Delta to Rate Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/deltatorateprocessor)
デルタ値をRateに変換。

- [Logs Transform Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/logstransformprocessor)
正規表現を使いログからフィールドを抽出。


### データ操作系

- [Filter Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/filterprocessor)
特定のAttribute（ホスト名やSeverityなど）を持つデータをIncludeもしくはExclude。

- [Group by Attributes processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/groupbyattrsprocessor)
特定のAttributeによりデータをグループ化。

- [Group by Trace processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/groupbytraceprocessor)
次のProcessorに渡す前に待機して同一TraceのSpanを収集。Tail Sampling Processorなどグループ化されたTraceが必要なProcessorの前で使用する。

- [Routing processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/routingprocessor)
Attributeを元にデータを特定のExporterにルーティング。

### データ作成系

- [Metrics Generation Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/metricsgenerationprocessor)
既存のメトリクスを計算して新しいメトリクスを生成。
1. 加算、減算、乗算、除算、パーセント　（複数メトリクスの組み合わせも可）
2. スケール（bytes ⇒ Mega bytes）

- [Span Metrics Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/spanmetricsprocessor)
SpanデータからRED (Request、Error、Duration)を集計。

- [Service graph processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/servicegraphprocessor)
Service Graph（分散システムのトポロジーなど）を作成するためのマップ作成。Grafanaで使うらしい。


### Custom Processor

上記の他にも、各ベンダーのOtel Distributionだったり、Github上にサードパーティーが作成されたProcessorがあります。どうしても足りなければGo言語で開発することもできます。


# まとめ

ざっとProcessorを眺めて見ました。
絶対に入れた方が良いExporterはmemory_limiter、batchで後はお好みで、という感じのようです。

サンプリング、Attributeの操作（リソース情報追加や機密情報マスキング）、フィルタリングなど柔軟な処理ができそうです。データ送信先のバックエンドは何でもよくて、Receiver、Processorは使いまわせるというOtelの良さを存分に発揮できますね。