はじめに

私の自宅には、常時動いているLinux PCが2台あります。その上でDNSやコンテナを動かして遊んでいるのですが、ときどきサービスが使えなくなって、なんならsshもできなくなっていて、仕方なく再起動させることがまれによくあります。

自分だけが使っているものなので、それでも良かったのですが、原因がわからないまま放っておくのも気持ちが悪くなってきたので止まる直前までPCがどのような状態であったのか把握できるようにモニタリング周りを整備しようと思いました。

最近、OpenTelemetryと周辺技術に興味を持っていたこともあったので、OpenTelemtryを中心に構成を考えました。この記事では、OpenTelemetry Collectorをエージェントとして利用してホストのメトリクスとログを収集し、Grafana Cloudに送信する方法について紹介います。

OpenTelemetry / OpenTelemetry Collector / Grafana Cloud について

OpenTelemetry

ベンダー非依存、オープンソースであり、ソフトウェアのオブザーバビリティを高めるための仕様やツールセットを提供しています。

https://opentelemetry.io/

OpenTelemetry Collector

テレメトリデータをOpenTelemetry Collectorに送信すると、任意のオブザーバビリティプラットフォームにデータをproxyすることができます。

https://opentelemetry.io/docs/collector/

今回はproxyとしての機能は使わずに、node_exporterやGrafana Agentのようなホストのメトリクスとログを収集するエージェントとして使っています。

Grafana Cloud

Grafana Labsが提供しているマネージドGrafanaです。無料枠が大きく、クレジットカードの登録なしで使えるので個人利用にはもってこいです。

https://grafana.com/products/cloud/

メトリクスとログを収集するためのOpenTelemetry Collectorの設定

OpenTelemetry Collectorは受信するテレメトリの様々なプロトコルに対応したり、エクスポート先を選べるようにするためにたくさんのコンポーネントで構成されています。2つのディストリビューション(otelcolotelcol-contribがありますが、どちらも今回の使用用途ではtoo fatです。

そこで、コマンドラインツールOpenTelemetry Collector builder (ocb)を使って、必要なコンポーネントのみで構成されたOpenTelemetry Collectorをビルドします。

以下のコマンドでインストールすることができます。ocbと呼ばれていますが、buiderというバイナリがインストールされます。

$ go install go.opentelemetry.io/collector/cmd/builder@latest

$ buider version
ocb version v0.94.1

ocbを使ってカスタムビルドを行う際のポイントは以下の2点です。

  1. 収集するテレメトリ、収集した後の処理、送り先を決める
  2. 1で決めた内容をビルドするためのマニフェトとして書く

収集するテレメトリ、収集した後の処理、送り先を決める

リリースされているOpenTelemetry Collectorには様々なコンポートネントが含まれていると説明しました。要するに、そのコンポーネントの中から必要なものを選ぶということになります。

今回のケースだと、以下のコンポーネントが必要になります。

  • ホストメトリクスとログを収集するコンポーネント hostmetricsreceiver & filelogreceiver
  • 収集したテレメトリをバッチで送るための処理をするコンポーネントbatchprocessor
  • Grafanaに送信するためのコンポーネント otlphttpexporter

上記は上から順に、ReceiverProcessorExporterというコンポーネントに分類されます。


各コンポーネントの詳細については私もちゃんと説明できるほど理解しきれていないのでこの記事では割愛させていただきます。興味がある方は以下のDocsやリポジトリを徘徊すると面白いかもしれません。


1で決めた内容をビルドするためのマニフェトとして書く

上記のコンポーネントを含むカスタムOpenTelemetry Collectorをビルドするためのマニフェストは以下になります。

# manifest.yaml

dist:
  name: custom-otelcol
  description: custom build otelcol for home server
  output_path: ./custom-otelcol
  otelcol_version: 0.94.0

extensions:
  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/extension/basicauthextension v0.94.0

exporters:
  - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.94.0

processors:
  - gomod: go.opentelemetry.io/collector/processor/batchprocessor v0.94.0

receivers:
  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver v0.94.0
  - gomod: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/filelogreceiver v0.94.0

必要なコンポーネントを並べただけのシンプルなyamlです。

$ builder --config=manifest-example.yaml

ビルドが成功すると、作業ディレクトリに以下のようなディレクトリが作られていて、そのなかにバイナリファイルがあると思います。

$ ll | grep custom-otelcol
drwxr-x--- 2 kumico kumico 4096 Feb 17 04:03 custom-otelcol

$ ll custom-otelcol | grep custom-otelcol
-rwxrwxr-x 1 kumico kumico 27963392 Feb 17 04:03 custom-otelcol

これでカスタムOpenTelemetry Collectorをビルドすることができました。

次にOpenTelemetry Collectorの設定ファイルを書いていきます。

OpenTelemetry Collectorの設定ファイル

設定ファイルには、Receiver、Processor、Exporterの細かい処理を定義するための設定を書いていきます。

# config.yaml

extensions:
  basicauth/otlp:
    client_auth:
      username: sample_user
      password: sample_password

receivers:
  hostmetrics:
    collection_interval: 60s
    scrapers:
      cpu:
      disk:
      filesystem:
      load:
      memory:
      network:
      paging:

  filelog:
    include:
      - /var/log/syslog
      - /var/log/auth.log

processors:
  batch:
    timeout: 1m

exporters:
  otlphttp:
    auth:
      authenticator: basicauth/otlp
    endpoint: https://otlp-gateway-prod-us-east-0.grafana.net/otlp

service:
  extensions: [basicauth/otlp]
  pipelines:
    metrics:
      receivers: [hostmetrics]
      processors: [batch]
      exporters: [otlphttp]
    logs:
      receivers: [filelog]
      processors: [batch]
      exporters: [otlphttp]

内容を簡単にまとめます。

  • Receiverの設定には、メトリクスの取得間隔と種類とログファイルを指定しています。
  • Processorにはtimeoutの設定
  • Exporterにはexport先のエンドポイント(上記はGrafana Cloudのotlp endpoint)と認証方法を設定しています。

書けたら、以下のようにバイナリ実行時の引数に上記の設定ファイルを渡せば、Grafana Cloudにデータが送信されると思います。

$ ./custom-otelcol --config=./config.yaml

Grafana CloudにはテレメトリをOpenTelemetry Protocol(OTLP)で直接送ることが可能なOTLP Endpoint URLがあります。コンソール画面から確認できるURLに対してBasic認証で送信することができます。

URLの設定手順に関しては、以下のページを参照してください。

https://grafana.com/docs/grafana-cloud/send-data/otlp/send-data-otlp/


送信されたメトリクスやログをGrafana Cloudで確認できました👀

screenshot-logs

screenshot-cpu-metrics

おわりに

OpenTelemetry Collectorでテレメトリを送信し始めてから2週間ほど経っていますが、エラーで落ちてテレメトリが送信できなくなるようなこともなく、自宅のPC上で動き続けています。ベンダーのエージェントに加えて、OpenTelemetry Collectorという選択肢も十分に入ってくるなと感じています。

おまけ systemdから操作するできるようにする

/etc/systemd/system/にユニットファイルcustom-otelcol.serviceをおく

[Unit]
Description=OpenTelemetry Collector
After=network.target

[Service]
ExecStart=/usr/local/bin/custom-otelcol --config=/etc/opentelemetry-collector-custom/config.yaml
ExecStop=/bin/kill -SIGTERM ${MAINPID}
Restart=always

[Install]
WantedBy=multi-user.target

適切に設定されていれば、systemdから操作することができる。

$ systemctl start custom-otelcol.service