Mackerelアドベントカレンダー2025 10日目の記事です。
Mackerelのメトリックには3種類あります。昔からあるホストメトリックとサービスメトリック、そして2024年に正式リリースされた「ラベル付きメトリック」です。今回は、Prometheusで構築されているメトリクス収集の仕組みを、OpenTelemetry Collector と Mackerel を使って、監視対象はそのままに Mackerel のラベル付きメトリックとして収集するように移行する手法を紹介します。
Prometheus のメトリック収集方法のおさらい
Prometheus を使ったメトリック収集の仕組みを、大雑把に説明すると以下のようになります。
- 監視対象(daemonやアプリケーション)がHTTPでメトリックを出力するエンドポイントを公開する
- Prometheusは定期的に監視対象にHTTPでアクセスし、出力されているメトリックを収集して保存する
つまり、Prometheus 自身が監視対象からメトリックをクロールする、というアーキテクチャです。いわゆるPull型ですね。1
Mackerel は基本的に、監視対象(agentなど)がMackerelのサーバーに向けてメトリックを送信する、Push型のアーキテクチャを採用しています。
ということで元々 Prometheus 用に作られたメトリック収集システムを Mackerel に置き換えるには、「監視対象が export しているメトリックを誰かが収集した上で Mackerel に向かって送信する」仕組みを作る必要があります。
OpenTelemetry Collector で解決
「誰かが収集した上で Mackerel に向かって送信する」仕組みを自作する必要はありません。Mackerel のラベル付きメトリックには OpenTelemetry 互換のAPI endpoint が用意されているため、OpenTelemetry Collector (otelcol) から送信できます。otelcol で Prometheus用にexportされたメトリックを収集するのためには prometheus receiver が使えます。これらを組み合わせるだけです。
otelcol の設定例
早速ですが設定例です。
- prometheus receiver でメトリックを収集
- 例では
myserverというjob名でmyservers.jsonに定義された対象の/metricsから60秒ごとに収集する
- 例では
- batch processor で1分ごとに送信をまとめる
- 収集するメトリックが多い場合、1分ではMackerel側に一度に送信できるサイズを超えてしまうことがあります
- その場合は1分よりも短い間隔に設定する必要があります
- 今では、batch processor を使わないより良いまとめ送りができるかもしれません。詳しくは あなたのOpenTelemetry CollectorのBatch Processorはもう不要かもしれない - Diary of a Perpetual Student を参照してください
- resouce processor でメトリックに属性を追加
service.namespaceとしてmyservicedeployment.environment.nameとして環境変数 ENV の値を設定
- otlp exporter で Mackerel のラベル付きメトリックAPIエンドポイントに送信
receivers: prometheus: config: scrape_configs: - job_name: myserver scrape_interval: 60s metrics_path: /metrics file_sd_configs: - files: - /etc/otel-collector/file_sd_configs/myservers.json processors: batch: timeout: 1m resource: attributes: - key: service.namespace value: myservice action: insert # https://opentelemetry.io/docs/specs/semconv/resource/deployment-environment/ - key: deployment.environment.name value: ${ENV} action: insert exporters: otlp/mackerel: endpoint: otlp.mackerelio.com:4317 compression: gzip headers: Mackerel-Api-Key: ${MACKEREL_APIKEY} debug: verbosity: basic service: pipelines: metrics: receivers: [prometheus] processors: [batch, resource] exporters: [otlp/mackerel]
この設定で otelcol を動作させておくことで、Prometheus 用に export されているメトリックをMackerelのラベル付きメトリックとして送信できます。簡単ですね!
小ネタ: 収集先ホスト一覧を mkr で用意する
収集対象のホスト一覧は、file_sd_configs を使って外部ファイルとして定義しています。こうすることで、otelcol を再起動せずに収集対象をメンテナンスできるようになります。
ファイル形式は以下のような JSON または YAML です。
[ { "targets": [ "192.168.0.1:9111", "192.168.0.2:9111", "192.168.0.3:9111" ] } ]
Mackerel でホストを管理している場合、mkr コマンドを使ってこのファイルを自動生成すると便利です。例えば以下のようにすると、Mackerel 上で定義されたホストのうち指定した条件のものでこの file_sd_config 用の定義を生成できます。
- サービス名: MyService
- ロール名: App
- ステータス: working のもの
- インターフェース名: eth0
$ mkr hosts \
--service MyService \
--status working --jq '[{"targets": [.[] | select(.roleFullnames | any(startswith("MyService:App"))) | .ipAddresses.eth0 + ":9111"] | sort}]'
定期的に実行しておけば、収集対象ホストの更新を完全に自動化できます。
小ネタ: Mackerel の「サービス」とOtelの「サービス」、概念の違い
Mackerel にも OpenTelemetry にも「サービス」という名前の概念があります。しかし少し残念なことに、この「サービス」が指す概念が異なっています。
- Mackerel のサービス: ある organization 内の独立した(例えばWebの)サービスを構築するホストをまとめたもの
- Otel のサービス: あるテレメトリ(メトリクス、ログ、トレース)を生成する論理的な単位 (アプリケーションやマイクロサービス、ミドルウェア)
- 例えば「nginx」や「MySQL」など
- Mackerel ではおおよそ、サービスの下の「ロール」に相当する概念
ということで、Otelcol が送信するメトリックの属性 service.name として相応しいのは、Mackerel の世界では「ロール」に相当します。Mackerel の世界の「サービス」を表す属性としては、Otel の世界では service.namespace を使うのがよいでしょう。
まとめ
この記事では、Prometheus で構築されたメトリック収集システムを、OpenTelemetry Collector を使うことで監視対象はそのままに Mackerel に移行する方法を紹介しました。
筆者の勤務するさくらインターネットのとある部署でも内部監視対象コンポーネントは主に Prometheus exporter で実装されていますが、この手法を利用することで Mackerel 上でのメトリック収集と監視を実現しています。
- Push型の Remote Write という仕組みもあります↩