OpenTelemetryでインフラメトリクス収集


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

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

# OpenTelemetryはインフラ監視にも使えちゃうぜ、というお話
OpenTelemetryと言えば分散トレーシングが注目されますが、用途はそれだけではなく、アプリが乗っているインフラやミドルウェアにも難なく適用できます。

今までホストはZabbixとかで監視してたけどクラウド移行 / コンテナ化するし、なんかマイクロサービスとかの噂も聞こえ始めてるけど、このままでいいのかな、、、と悩めるインフラエンジニアにご参考になれば幸いです。

# 早速Otelインストール

OtelはDocker、Kubernetes、Linux、Windows、MacOSなどに対応しています。

https://opentelemetry.io/docs/collector/getting-started/

今回は機能拡張版のOtel Collector Contrib版を使います。
Linuxの場合は各パッケージが提供されています。
※後続でデータをSplunk Observability Cloudに送信しています。本家のOtelでもいいですが、[SplunkのOtel Distribution](https://docs.splunk.com/Observability/gdi/opentelemetry/install-linux.html)を使うともっと便利です。

https://github.com/open-telemetry/opentelemetry-collector-releases/releases

とりあえずUbuntuにインストールしたいと思います。
※今回は手動でOtelをインストールしますが、もちろんAnsibleやPuppetなどで配布することもできます。

```sh: Otel install
wget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.67.0/otelcol-contrib_0.67.0_linux_amd64.deb
sudo apt install ./otelcol-contrib_0.67.0_linux_amd64.deb -y
```

これだけ。

お次はメトリクスの送信設定です。
Contrib版は`/etc/otelcol-contrib/config.yaml`に書いていきます。

Otelを初めて使う方は設定方法に面食らうと思います。
詳細は他の方の記事に譲りますが、OtelはReceiver（データ収集）、Processor（データ処理）、Exporter（データ送信）の三つのコンポーネントからなります。
それらの定義を`config.yaml`に書けばOKです。

## Receiver

Receiver一覧は[こちら](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver)。

Hostに関しては[Hostmetrics Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/hostmetricsreceiver)というものが使えます。CPU、メモリ、ディスク、プロセスなどに関するメトリクスを収集できます。フィルタなどかけられますが、とりあえずフルコースで収集します。

```text: /etc/otelcol-contrib/config.yaml : Hostmetrics Receiver例
receivers:
  hostmetrics:
    collection_interval: 10s
    scrapers:
      cpu:
      disk:
      load:
      filesystem:
      memory:
      network:
      paging:
      processes:
      process:
```

## Processor

Processor一覧は[こちら](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor)。

お次はProcessorです。
Processorはなくても動くには動きます。しかしデフォルトではホスト名すら取ってくれない仕様なので、いい感じにリソース情報を取ってくれる[Resource Detection Processor](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/resourcedetectionprocessor#readme)を使います。


```text: /etc/otelcol-contrib/config.yaml : Resource Detection Processor例
processors:
  resourcedetection:
    detectors: [ec2]
```

今回はEC2上のubuntuを使っているので`ec2`を指定しました。これにより以下情報を自動で収集しメトリクスにDimentionとして付与してくれます。

```
* cloud.provider ("aws")
* cloud.platform ("aws_ec2")
* cloud.account.id
* cloud.region
* cloud.availability_zone
* host.id
* host.image.id
* host.name
* host.type 
```

## Exporter

Exporter一覧は[こちら](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter)。

最後にデータの送信先です。今回は[SignalFx Metrics Exporter](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/signalfxexporter)を使い、Splunk Observability Cloudに送信します。

```sh: /etc/otelcol-contrib/config.yaml : Exporter例
exporters:
  signalfx:
    access_token: "*****"
    realm: "*****"
```

ちなみにOtelの特長は、宛先はOtelに対応しているツールであれば何でもいい所です。
[対応ベンダー一覧](https://opentelemetry.io/vendors/)にある通り、GrafanaでもElasticでも良いです。
Exporterの設定さえ変えてあげればReceiver、Processorに手を加える必要はありません。

## Pipeline

これまで行ってきたのは、それぞれの定義のみです。
定義を使用するにはPipelineを組み立てます。

```text: /etc/otelcol-contrib/config.yaml : Pipeline例
service:
  pipelines:
    metrics:
      receivers: [otlp, opencensus, prometheus, hostmetrics]
      processors: [batch, resourcedetection]
      exporters: [signalfx]
```

上記の通り、これまで定義してきたReceiver、Processor、Exporterの定義名を指定しています。
デフォルトで入っているものはとりあえず残しています。
これで`config.yaml`は完成です。

## 設定有効化

Otelを再起動して有効化します。

```sh
sudo systemctl restart otelcol-contrib
```

ログは以下で見れます。

```sh
sudo journalctl | grep otelcol-contrib
```

## 見てみる

Splunk Observability CloudのInfrastructure Monitoringで確認すると、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/3ee713ea-ad2b-3789-f268-e5ba6cf8ba38.png)

素晴らしい！


## ついでにミドルウェアも

Nginxが稼働しているとして、Nginxのメトリクスも収集したいと思います。
[Nginx Receiver](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver/nginxreceiver)の出番です。

Nginx用のReceiver定義を作りPipelineのreceiversに追加します。

```text: /etc/otelcol-contrib/config.yaml : Nginx追加
receivers:
  nginx:
    endpoint: "http://localhost:80/status"
    collection_interval: 10s

service:
  pipelines:
    metrics:
      receivers: [otlp, opencensus, prometheus, hostmetrics, nginx]
      processors: [batch, resourcedetection]
      exporters: [signalfx]
```

Otel再起動すると、、、

```sh
sudo systemctl restart otelcol-contrib
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/423379db-154d-c53e-26b6-cc06c4c4cdcb.png)

素晴らしい！！！

最後に、今回作った`config.yaml`の全体像です。
※今回特に触れていなかったデフォルトの設定も入っています。

```text: config.yaml
extensions:
  health_check:
  pprof:
    endpoint: 0.0.0.0:1777
  zpages:
    endpoint: 0.0.0.0:55679

receivers:
  otlp:
    protocols:
      grpc:
      http:

  opencensus:

  # Collect own metrics
  prometheus:
    config:
      scrape_configs:
      - job_name: 'otel-collector'
        scrape_interval: 10s
        static_configs:
        - targets: ['0.0.0.0:8888']

  jaeger:
    protocols:
      grpc:
      thrift_binary:
      thrift_compact:
      thrift_http:

  zipkin:

  hostmetrics:
    collection_interval: 10s
    scrapers:
      cpu:
      disk:
      load:
      filesystem:
      memory:
      network:
      paging:
      processes:
      process:

  nginx:
    endpoint: "http://localhost:80/status"
    collection_interval: 10s

processors:
  batch:

  resourcedetection:
    detectors: [ec2]

exporters:
  logging:
    logLevel: debug

  signalfx:
    access_token: "*****"
    realm: "*****"

service:

  pipelines:

    traces:
      receivers: [otlp, opencensus, jaeger, zipkin]
      processors: [batch]
      exporters: [logging]

    metrics:
      receivers: [otlp, opencensus, prometheus, hostmetrics, nginx]
      processors: [batch, resourcedetection]
      exporters: [signalfx]

  extensions: [health_check, pprof, zpages]


```



# それで何？

Otelの真骨頂は、いわゆるオブザーバビリティ三本柱のMetrics、Trace、Logを一手に賄えることにあります。
アプリと同様にインフラ部分のメトリクスもOtelで取って、同じバックエンドに送ってあげれば、トラブルシューティング時にアプリ側の問題なのかインフラ側の問題なのか瞬時に切り分けることができます（もちろん、バックエンドでそのような相関分析の機能があればですが）。

※ログと言えば、Advent Calendar一日目の[OpenTelemetry Collectorでログファイルの更新を取り込む](https://katzchang.hatenablog.com/entry/tailing_file_with_otel_collector)も参考になります。


それでは良いOtelライフを！