Grafana Alloyのインストールと使い方ガイド:Prometheus Agent、Promtail、OpenTelemetry Collectorを1つのテレメトリ収集ツールに統合する

Monitoring tutorial - IT technology blog
Monitoring tutorial - IT technology blog

私はPrometheus Agent + Promtail + OpenTelemetry Collectorのスタックを本番環境でほぼ1年間並行して運用していました。3つのバイナリ、3つの設定ファイル、3つのsystemdサービス — アップデートのたびに頭を悩ませていました。Grafana Alloyに移行してから、テレメトリ収集パイプライン全体が1つのバイナリに収まりました。6ヶ月の実運用から学んだことをまとめます。

5分でAlloyをインストールして起動する

Ubuntu/Debianへのインストール

# Grafana APTリポジトリを追加
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee /etc/apt/sources.list.d/grafana.list

# Alloyをインストール
sudo apt-get update
sudo apt-get install -y alloy

最小限のConfig — すぐにメトリクスとログを収集する

以下の内容で/etc/alloy/config.alloyファイルを作成します:

// node_exporterからメトリクスを収集(Prometheusスクレイプの代替)
prometheus.scrape "node_exporter" {
  targets    = [{"__address__" = "localhost:9100"}]
  forward_to = [prometheus.remote_write.main.receiver]
}

// Prometheus/Mimirへメトリクスを送信
prometheus.remote_write "main" {
  endpoint {
    url = "https://your-mimir-endpoint/api/prom/push"
    basic_auth {
      username = "your-username"
      password = "your-api-key"
    }
  }
}

// systemdジャーナルからログを収集(Promtailの代替)
loki.source.journal "systemd" {
  forward_to = [loki.write.main.receiver]
}

// Lokiへログを送信
loki.write "main" {
  endpoint {
    url = "https://your-loki-endpoint/loki/api/v1/push"
    basic_auth {
      username = "your-username"
      password = "your-api-key"
    }
  }
}
# Alloyを起動してenableにする
sudo systemctl enable alloy
sudo systemctl start alloy

# 状態を確認
sudo systemctl status alloy

# ログを監視
sudo journalctl -u alloy -f

完了です。Alloyはnode_exporterのメトリクスをスクレイプし、systemdからログを転送しています — 以前は2つの別々のエージェントが必要だったことが、1つのプロセスで動作しています。

Alloyとは何か、そのアーキテクチャが異なる理由

Grafana Alloyは2024年にリリースされ、Grafana Agent(Flowモード)を継承しています。Prometheus AgentやPromtailとは異なり、AlloyはOpenTelemetry Collectorをベースに構築され、PrometheusとLokiエコシステム両方のネイティブコンポーネントを追加しています — 1つのバイナリで3種類すべてのテレメトリを処理します。

Alloy以前、各サーバー上の典型的なモニタリングスタックには以下が必要でした:

  • Prometheus Agent — メトリクスのスクレイプ、remote write
  • Promtail — ログの収集、Lokiへの送信
  • OpenTelemetry Collector — アプリケーションからtracesを収集

3つの別々のプロセス、3つの異なる設定構文。午前3時にどれかがクラッシュすると、1つずつデバッグしなければなりません。Alloyはこれらすべてを統合します。

すべてがコンポーネント

AlloyのConfig構文はHCL風の構文を使用し、各要素はinputとoutputを持つコンポーネントです。これらをつなぎ合わせてパイプラインを構成します:

// コンポーネントAがデータを生成 → コンポーネントBへforward
component_type_a "my_label" {
  forward_to = [component_type_b.my_label.receiver]
}

component_type_b "my_label" {
  // component_aからデータを自動受信
}

まるでLego — パイプラインの順序に従ってブロックを組み合わせるだけです。この方法は、Promtailのフラットなconfig YAMLよりもデバッグが容易です:グラフを見るだけで、データがどのコンポーネントで滞っているかがすぐにわかり、ログを1行ずつ追う必要がありません。

高度な設定

複数のソースから同時にログを収集する

// アプリケーションのログファイルを読み込む
loki.source.file "app_logs" {
  targets = [
    {__path__ = "/var/log/nginx/access.log", job = "nginx", env = "production"},
    {__path__ = "/var/log/myapp/*.log",      job = "myapp", env = "production"},
  ]
  forward_to = [loki.write.local.receiver]
}

// systemdジャーナルを読み込み、journalフィールドからラベルを追加
loki.source.journal "system" {
  forward_to    = [loki.write.local.receiver]
  relabel_rules = loki.relabel.journal_labels.rules
}

loki.relabel "journal_labels" {
  rule {
    source_labels = ["__journal__systemd_unit"]
    target_label  = "unit"
  }
  forward_to = []
}

loki.write "local" {
  endpoint {
    url = "http://loki:3100/loki/api/v1/push"
  }
}

アプリケーションからOpenTelemetry tracesを受信する

// gRPC(4317)とHTTP(4318)でtracesを受信
otelcol.receiver.otlp "default" {
  grpc { endpoint = "0.0.0.0:4317" }
  http { endpoint = "0.0.0.0:4318" }

  output {
    traces = [otelcol.exporter.otlp.tempo.input]
  }
}

// Tempoへtracesを転送
otelcol.exporter.otlp "tempo" {
  client {
    endpoint = "tempo:4317"
    tls { insecure = true }
  }
}

DockerのService discovery

// 実行中のすべてのコンテナを自動スクレイプ
discovery.docker "containers" {
  host = "unix:///var/run/docker.sock"
}

prometheus.scrape "docker_targets" {
  targets         = discovery.docker.containers.targets
  forward_to      = [prometheus.remote_write.main.receiver]
  scrape_interval = "30s"
}

組み込みUIによるデバッグ

私が最もよく使っていて、あまり注目されていない機能:Alloyにはポート12345でWeb UIが用意されています。http://localhost:12345にアクセスすると、コンポーネントパイプライン全体のグラフをフローチャート形式で確認でき、各コンポーネントのヘルス状態や各ステージを流れるデータも確認できます。

# SSHトンネル経由で安全にアクセス
ssh -L 12345:localhost:12345 user@your-server
# その後、ローカルマシンでhttp://localhost:12345を開く

6ヶ月の本番運用で得た実践的なTips

1. アラート疲れを防ぐコンテキストラベルを追加する

モニタリングをセットアップしたばかりの頃、閾値の設定を誤って頻繁にアラートを受け取っていました — stagingでのCPU 70%がproductionと同じようにアラートを出していたのです。解決策:Mimirに送信する前にAlloyでコンテキストラベルをinjectし、その後environmentでフィルタリングするAlertmanagerルールを記述しました:

// remote write前にすべてのメトリクスにenvironmentラベルを追加
prometheus.relabel "add_context" {
  rule {
    target_label = "environment"
    replacement  = "production"
  }
  rule {
    target_label = "region"
    replacement  = "ap-northeast-1"
  }
  forward_to = [prometheus.remote_write.main.receiver]
}

結果:CPUが80%を超え、かつenvironmentが「production」の場合にのみアラートが発火するようになりました。stagingとdevは静かなままです。

2. ダウンタイムなしでConfigを検証・リロードする

# フォーマットと構文チェック
alloy fmt /etc/alloy/config.alloy

# サービスを再起動せずにconfigをリロード
sudo systemctl reload alloy

# またはHTTP API経由で
curl -X POST http://localhost:12345/-/reload

3. Promtailからの自動マイグレーション

GrafanaにはPromtailの設定をAlloyフォーマットに変換するツールが用意されています:

alloy convert \
  --source-format=promtail \
  --output=/etc/alloy/config.alloy \
  /etc/promtail/config.yml

このツールのおかげで、ある午後に12台のサーバーをマイグレーションできました。出力は100%完璧ではなく — いくつかのラベルルールは手動で調整が必要でしたが — 最初から手書きする場合と比べて約70%の時間を節約できました。

4. 実際のリソース使用量

2 vCPU / 4GB RAMのサーバーで、約50のスクレイプターゲットと3つのサービスからのログ収集を実行した場合の測定値:

  • Alloy:RAM約80MB、平均CPU約2%
  • 以前の3つの別エージェント:合計RAM約250MB

差は約170MB。小さく聞こえますが、1GB VPSやRaspberry Pi上のエッジノードでは実際に体感できる数値です — 私の小さなサーバーのいくつかはエージェントがRAMを食いつぶしてswapしていましたが、Alloyに移行してからはそれがなくなりました。

5. Dockerで実行する

docker run -d \
  --name alloy \
  --network host \
  -v /etc/alloy:/etc/alloy \
  -v /var/log:/var/log:ro \
  -v /run/log/journal:/run/log/journal:ro \
  -v /etc/machine-id:/etc/machine-id:ro \
  grafana/alloy:latest \
  run /etc/alloy/config.alloy

Grafana Alloyは万能薬ではありません。メトリクスのスクレイプだけが必要で、LokiやtracesにさわらないスタックならシンプルなPrometheusの方がシンプルです — 可動部品が少なく、コミュニティも大きい。しかし3種類すべてのテレメトリが必要な場合、Alloyは柔軟性を犠牲にすることなく、多くの運用上の手間を削減してくれます。

Share: