11 人が閲覧(直近 30 日) 監視・オブザーバビリティ

Prometheusで監視を構築する手順|exporter設計・PromQL・保持期間の見積り

Prometheusで監視を構築する手順|exporter設計・PromQL・保持期間の見積り

Prometheusは、監視対象がHTTPで公開している数値をサーバ側から取りに行き、時系列として溜めてから問い合わせる監視ツールです。エージェントに設定を配って送らせるのではなく、Prometheus側が宛先の一覧を持って定期的に取得する。この向きの違いが、設定の置き場所からディスクの見積りまでを決めます。この記事では、pull方式の構造、docker composeで本体とnode_exporterを動かす最小構成、PromQLの型合わせ、Alertmanagerの設定、保持期間とディスク容量の逆算、3系へ上げるときに壊れる箇所までを公式ドキュメントの記述を出典として整理しました。

まとめ:Prometheusの導入手順と自前運用が限界に届く分岐点

Prometheusがやることは3つに畳めます。第1に、宛先リスト(scrape_configs)に並んだエンドポイントへHTTPで取りに行く。第2に、メトリクス名とラベルの組で識別される時系列としてローカルのTSDBへ書く。第3に、PromQLの結果をルールに掛け、閾値を超えたらAlertmanagerへ渡す。公式のOverviewには、収集はHTTPのpullモデルで実施し、短命なジョブだけ中間ゲートウェイ経由のpushを併用すると書かれています。

導入は3工程です。まず本体とexporterを立てる。次に prometheus.yml に job を並べ、9090番のUIでターゲットがUPになっているかを見る。最後にルールファイルとAlertmanagerを足して通知経路を繋ぐ。

判断が要るのはその先です。ローカルストレージはクラスタリングもレプリケーションもされないため、1台のディスクとメモリが上限になります。保持期間の既定は15日で、数か月分を持つならremote writeで外へ出す設計に切り替える。監視対象が数十台まで・保持が数週間なら自前運用が成立し、数百台規模や長期保存が要件に入った時点でマネージドか分散実装へ寄せたほうが総コストは下がります。

pull方式でHTTP経由でメトリクスを取得する仕組みと構成要素

Prometheusの挙動が読めなくなる原因は、ほぼデータモデルとpullの向きに集まります。先に構造を掴むと調査が短く済みます。

メトリクス名とラベルの組み合わせで時系列を識別するデータモデル

公式のOverviewは、Prometheusを「メトリクス名とキー・バリューペア(ラベル)で識別される時系列データ」を扱う多次元データモデルとして説明しています。node_cpu_seconds_total という名前に cpu="0" や mode="idle" が付くたび、別の時系列として独立して積まれる。ラベルの組み合わせの数がそのまま本数になるため、ユーザーIDのような値を入れると爆発します。

exporterが返す本文は次のようなテキストで、# HELP と # TYPE の行が説明と型を示します。

# HELP node_cpu_seconds_total Seconds the CPUs spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 102345.67
node_cpu_seconds_total{cpu="0",mode="system"} 512.31
node_cpu_seconds_total{cpu="1",mode="idle"} 101988.02
# HELP node_filesystem_avail_bytes Filesystem space available.
# TYPE node_filesystem_avail_bytes gauge
node_filesystem_avail_bytes{device="/dev/sda1",mountpoint="/"} 4.2949673e+10

counter は積み上がり続ける累積値、gauge はその瞬間の値です。_total で終わる名前は累積で、この型の差がPromQLの書き方を決めます。

pull方式が前提になる理由とpush gatewayを挟む場面

Prometheusは宛先を自分で持ち、間隔を決めて取りに行きます。監視対象が増えても設定を配布し直す必要がなく、サービスディスカバリと組めば起動したインスタンスを自動で拾える。逆に、動いて終わる短命なジョブは取りに行った瞬間には消えています。この場合だけ、公式が構成要素に挙げるpush gatewayを間に置き、ジョブ側から値を預ける形にします。Istioのサービスメッシュのメトリクスは Istio Prometheus連携の設定:istio_requests_totalの収集とGrafana・Kialiでの可視化 で解説しています。

取りに行く側が主体という設計は、Prometheusが生まれた経緯とも繋がっています。成立の背景はPrometheusの誕生とCloud Native Computing Foundationとの関係に整理しました。送る側を統一するOpenTelemetryとの線引きはOpenTelemetry(OTel)とは|3つのシグナル・OTLP・Collectorとの違いを解説で扱っています。

exporterを挟んでPrometheus形式へ変換する構成要素の全体像

監視対象がPrometheus形式を話さない場合は、間にexporterを挟みます。公式が挙げる構成要素は、本体・クライアントライブラリ・push gateway・exporter群・Alertmanagerの5つ。全部を最初から入れる必要はなく、本体とexporterだけで監視は始まります。

Prometheus本体とnode_exporterをcomposeで動かす手順

ここからは実際に動く構成です。バージョンは Prometheus v3.14.0(2026-08-18公開)、node_exporter v1.12.1(2026-07-14公開)を使います。いずれもGitHub Releasesで確認した取得時点の値です。

compose.yamlに本体とexporterを並べる最小構成

次のcompose定義で、本体とnode_exporterが同時に上がります。保持期間はあとで触るので、この段階でフラグとして明示しておきます。

services:
  prometheus:
    image: prom/prometheus:v3.14.0
    ports: ["9090:9090"]
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prom-data:/prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
      - --storage.tsdb.retention.time=30d
  node-exporter:
    image: quay.io/prometheus/node-exporter:v1.12.1
    pid: host
    volumes:
      - /:/host:ro,rslave
    command:
      - --path.rootfs=/host
volumes:
  prom-data:

バイナリで動かす場合の起動は、Getting startedの記述どおり ./prometheus --config.file=prometheus.yml の1行です。立ち上がったら localhost:9090 がUI、localhost:9090/metrics がPrometheus自身のメトリクスになります。

prometheus.ymlのscrape_configsでジョブを定義する

設定の骨格は次のとおりです。global に全体の間隔を書き、scrape_configs に job を並べる。job ごとに間隔を上書きできます。

global:
  scrape_interval: 15s
  evaluation_interval: 15s
  external_labels:
    monitor: 'prod-monitor'

rule_files:
  - 'rules/*.yml'

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    scrape_interval: 30s
    static_configs:
      - targets: ['node-exporter:9100']
        labels:
          group: 'production'

書式は設定リファレンスに定義されています。scrape_interval を短くすると解像度は上がる一方、後述の見積り式どおりサンプル数が線形に増えてディスクを食う。既定の15秒から始め、必要なjobだけ短くします。

node_exporterをホスト監視に使うときのマウント指定

node_exporterはサーバのCPU・メモリ・ディスク・ネットワークを集めて既定で9100番に出す実装です。READMEには --collector.<name> で有効化、--no-collector.<name> で無効化、--collector.disable-defaults と組み合わせて特定のコレクタだけを動かせると書かれています。コンテナからホストを見るときは、同じREADMEの実行例のとおりホストのルートを読み取り専用でバインドマウントし、--path.rootfs にそのマウント先を渡す。

docker run -d \
  --net="host" \
  --pid="host" \
  -v "/:/host:ro,rslave" \
  quay.io/prometheus/node-exporter:v1.12.1 \
  --path.rootfs=/host

この指定を落とすと、コンテナ自身のファイルシステムを見た値が返ります。ディスク使用率が実際と合わないときは、まずここを疑ってください。

GPUサーバーを監視対象に加える場合は、node_exporterと並べてNVIDIAのdcgm-exporterを置きます。手元での確認に使うnvidia-smiの読み方から常駐監視へ移す判断まではnvidia-smiの使い方|GPU使用率とメモリの見方・CSV記録・DCGMへの移行判断にまとめました。

PromQLの4つの型を揃えてrateとhistogramを読む

PromQLで結果が空になる、あるいはエラーになる原因のほとんどは型の不一致です。クエリの基礎には、式が instant vector・range vector・scalar・string の4つに評価されると書かれています(stringは現状使われていません)。

instant vectorとrange vectorを取り違えたときの症状

instant vectorは各時系列につき1点だけを持つ集合、range vectorは一定期間の複数点を持つ集合です。[5m] を付けると range vector、付けなければ instant vector のまま。公式は rate が range vector を入力に要求すると明記しており、rate(node_cpu_seconds_total) はエラーになる。逆に比較は instant vector を前提にするため、range vector を > の左に置いても通りません。

期間の単位は ms から y までで、1h30m のような連結も書けます。過去の時点を見る offset と絶対時刻で評価する @ も併用でき、その場合の offset は @ の時刻を基準に適用されます。

ラベルマッチャの4種類と正規表現が完全アンカーされる挙動の注意

ラベルの絞り込みは =(一致)・!=(不一致)・=~(正規表現一致)・!~(正規表現不一致)の4つ。ここで引っかかるのが、正規表現が完全アンカーされる仕様です。env=~"foo" は env=~"^foo$" として扱われるため、部分一致を期待して書くと何も返らず、前後に .* を足す必要があります。

rateとhistogram_quantileでレイテンシを出す書き方

実務で最初に書くのは、この4本あたりです。上から順に、CPUのidle時間の増加率、instanceごとのCPU使用率、95パーセンタイルのレイテンシ、落ちているターゲットの数を出しています。

rate(node_cpu_seconds_total{mode="idle"}[5m])

100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

histogram_quantile(0.95,
  sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

count(up == 0)

histogram_quantile は le ラベルを持つ _bucket 系列を前提にするため、集約するときも le を残す。アプリ側でこの形のメトリクスを出す実装は、PHPでの具体例をLaravelでPrometheusとGrafana監視を実装:メトリクス収集・可視化・アラート設定にまとめてあります。計装側と基盤側を合わせて読むと収集から可視化までが繋がる。

アラートルールとAlertmanagerで通知経路を組み立てる

閾値を超えたことに気付く仕組みは、Prometheus側のルール評価とAlertmanager側の集約に分かれています。どちらの層で何を調整するかを分けて持つと、通知が多すぎる問題に手を入れやすい。

forでpendingを挟んでフラッピングを抑えるルールの定義

アラートルールのリファレンスによると、for は発火と見なされるまでの待機期間で、その間の状態は pending です。for を書かないルールは最初の評価でいきなり active になり、瞬間的な値の跳ねがそのまま通知になります。

groups:
  - name: node
    rules:
      - alert: InstanceDown
        expr: up == 0
        for: 5m
        keep_firing_for: 10m
        labels:
          severity: page
        annotations:
          summary: "{{ $labels.instance }} が応答していない"

      - alert: DiskWillFillIn24h
        expr: predict_linear(node_filesystem_avail_bytes[6h], 24*3600) < 0
        for: 30m
        labels:
          severity: warning
        annotations:
          summary: "24時間以内にディスクが枯渇する見込み"

keep_firing_for は、発火条件が最後に満たされた後もアラートを firing のまま保つ期間です。条件が閾値の前後を行き来する対象では、この2つを組み合わせて通知の往復を抑えます。

Alertmanagerのgroup_byとrepeat_intervalの設計

Alertmanagerの設定では、group_wait の既定が30秒、group_interval が5分、repeat_interval が4時間と定義されています。同じ原因で大量に発火したものを1通にまとめる単位が group_by です。

route:
  group_by: ['alertname', 'instance']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: default

receivers:
  - name: default
    webhook_configs:
      - url: 'https://example.internal/hooks/alert'

inhibit_rules:
  - source_matchers: [severity="critical"]
    target_matchers: [severity="warning"]
    equal: ['alertname', 'instance']

inhibit_rules は、上位のアラートが出ている間だけ下位を黙らせる指定です。equal に挙げたラベルの値が両者で一致したときに抑制が効く。ホストが落ちているのにプロセス監視まで別々に鳴る状況は、これで1本に畳めます。

ALERTSメタメトリクスで発火とpendingを後から追跡する

Prometheusは評価の結果を ALERTS{alertname="...",alertstate="pending"} のような合成時系列として自分の中に書き、状態が続く間は値1を保ちます。夜間に鳴った回数を数える、pendingで止まって firing まで届いていないルールを洗い出す、といった振り返りはこの系列で行える。通知ログを別途集める前に、まずここを見ると早い。

ローカルTSDBの保持期間とディスク容量を計算式で見積もる手順

Prometheusで最初に見誤るのがディスクです。ストレージのドキュメントに計算式まで書かれているので、稼働前にあてておきます。

2時間ブロックとcompactionが動く区切りと上限の決まり

取り込んだサンプルは2時間単位のブロックにまとめられます。その後のcompactionで大きなブロックへ束ねられ、上限は「保持時間の10%」か「31日」の小さいほう。書き込み中のデータはWALに置かれ、128MBのセグメントで最小3ファイルが保持されます。

retention.timeとretention.sizeの既定値と落とし穴

保持の指定は2種類です。どちらも明示しない場合、時間側の既定が効きます。

フラグ(–storage. 以下) 既定値 役割
tsdb.retention.time 15d 期間で古い分を捨てる
tsdb.retention.size 0(無効) 総量の上限で捨てる
tsdb.path data/ ブロックとWALの置き場

落とし穴は2つあります。1つは、既定のまま動かして「先月のグラフが無い」と気付く流れ。15日で消えるため四半期の傾向は追えません。もう1つはサイズ側が既定で無効という点。満杯になるまで書き続けるので、他のプロセスとディスクを共有する構成では両方を指定します。

WALとブロックを含めた必要ディスク容量の逆算と実測の突き合わせ

公式が示す式は次のとおりです。1サンプルあたりのバイト数は平均1〜2バイトという目安が併記されています。

# needed_disk_space =
#     retention_time_seconds
#   * ingested_samples_per_second
#   * bytes_per_sample

# 例: 毎秒1万サンプルを30日保持する
#   30d = 2,592,000 秒
#   bytes_per_sample = 2 バイト(安全側)
2,592,000 * 10,000 * 2 = 51,840,000,000 バイト
                       = 約 52 GB(10進表記)

毎秒のサンプル数は rate(prometheus_tsdb_head_samples_appended_total[5m]) で実測でき、その値を式に入れればいま動いている構成での消費が出ます。減らす手は、保持期間を縮めるか、スクレイプ間隔を延ばすか、時系列の本数を削るかの3択。3つめが効くのは、ラベルの粒度が細かすぎるケースです。

ローカルストレージが冗長化されない前提とremote writeの逃げ道

ドキュメントは、ローカルストレージがクラスタリングもレプリケーションもされず、したがって任意にスケールしないと明言しています。1台のPrometheusが持てる範囲がそのまま上限になる、という前提で設計する。超える場合の出口はリモートストレージへの統合ですが、PromQLの評価自体はPrometheus側で実行されるため、外へ出してもクエリの負荷が全部消えるわけではありません。

メトリクス以外のシグナルは別の受け皿を用意します。ログはGrafana Lokiとは?Prometheus連携・LogQL・導入方法をわかりやすく解説、分散トレースはGrafana Tempoとは?分散トレーシングの仕組み・TraceQL・導入判断を実装者向けに解説で扱っています。3つを同じラベル体系で揃えておくと、アラートから該当ログへ辿る動線が作れる。

2系から3系へ上げるときにPromQLと設定が壊れる箇所と対処

3系への移行で厄介なのは、起動が失敗する変更より黙って結果が変わる変更です。3.0の移行ガイドから、実装者が踏みやすいものを拾います。

range selectorが左端排他になりサブクエリの点数が変わる

lookbackとrange selectorが、左端を含まない形(left-open・right-closed)へ変わりました。サンプルのタイムスタンプが範囲の左端とちょうど一致する場合、その点が対象から外れる。ガイドはサブクエリでの影響を例示しており、foo[1m:1m] が2点から1点を返すようになると書かれています。影響が出るのは、範囲と間隔が同じ長さで並ぶ書き方や点数が少ない集約です。

正規表現のドットが改行にマッチする挙動の変更と修正箇所の探し方

. が改行文字にもマッチするようになったため、.* が複数行にまたがります。2系と同じ結果に戻すには該当箇所を [^\n] へ置き換えるとガイドは示しています。ルールファイルとダッシュボードの定義を =~ と !~ で全文検索し、改行を含みうるラベル値に当たっているものだけを直す順が早い。

削除されたフラグとfallback_scrape_protocolの追加

--enable-feature で渡していた実験フラグは9個が削除されました。promql-at-modifier や promql-negative-offset は既定で有効になり、no-default-scrape-port はポートの自動付与そのものが廃止。エージェントモードは --agent、書き込み受信は --web.enable-remote-write-receiver という専用フラグへ移りました。起動オプションをそのまま持ち込むと落ちる箇所です。

Content-Typeヘッダが不備なターゲットに3系はフォールバックせず失敗するため、自作のexporterがあるなら scrape設定に fallback_scrape_protocol を明示します。remote writeの http_config.enable_http2 は既定が false へ変わり、メトリクス名とラベル名はUTF-8が既定で通るようになった(戻すなら metric_name_validation_scheme: legacy)。TSDBの形式はv2.55で変わっており、切り戻す先はv2.55までと決まっているため、上げる前にこの版へ寄せておくと退路が残ります。

受託開発でPrometheusを自前運用する条件と見送る場面の判断

Prometheusは入れるところまでが容易な一方、溜まったデータの面倒を誰が見るかで運用コストが決まります。

自前でPrometheusを建てる条件とマネージドに寄せる線引き

自前運用が成立する条件は3つ揃ったときです。第1に監視対象が数十台規模でおさまり、時系列の本数が1台のメモリに乗る。第2に保持が数週間から1か月で足り、長期の傾向分析を別系統に任せられる。第3に、ラベル設計とルールを直せる担当が社内にいる。

見送る場面もはっきりしています。100%の正確さが要る用途には向きません。公式のOverviewが、リクエスト単位の課金では適切でないと明記しているとおり、取りこぼしを前提にした仕組みだからです。課金や監査の根拠にする数値は別の台帳で持つ。マルチテナント、年単位の保持、監視基盤自体の可用性が要件に入るなら、分散実装かマネージドへ寄せたほうが早い。

ネットワーク機器やWindowsサーバが主体で対象が固定的な環境では、エージェント型が扱いやすい。判断材料はZabbixとは?仕組み・監視できること・他ツールとの違いをわかりやすく解説に整理してあります。コンテナが増減する環境ならPrometheus、台数が固定で機器監視が中心ならエージェント型、という分け方が現実的です。

監視の設計とアラート運用を内製へ引き継ぐまでの支援と役割の分担

監視は入れた日ではなく、鳴り続けた3か月後に評価が決まります。誰も見ないアラートが増えた状態を放置すると、本当の障害が埋もれる。一創では、ラベル設計とルールの初期構築、しきい値の見直し、通知経路の整理までを保守運用 / 内製化支援として引き受け、運用の判断を社内へ戻すところまでを範囲にしています。構築だけを外に出して運用が回らない形は避けたいので、ルールの追加と削除を自分たちで判断できる状態を到達点に置きます。

よくある質問

Prometheusはどんなシステムに向いていますか?

純粋な数値の時系列を記録する用途と、マイクロサービスのように次元が多いデータを扱う用途です。公式のOverviewがこの2つを適合例として挙げています。1件も取りこぼせない数値、たとえばリクエスト単位の課金には向かないと明記されているため、その手の数値は別系統で持つ。

ZabbixとPrometheusはどちらを選ぶべきですか?

監視対象の増減のしかたで決まります。コンテナやクラウドのインスタンスが動的に入れ替わる環境ではPrometheusのサービスディスカバリが効き、設定の配布が要りません。台数が固定でネットワーク機器やWindowsが中心なら、エージェント型のほうが導入が短く済む。両方を並べて対象ごとに分担させる構成も現実的です。

メトリクスが増えたときは何から手を入れますか?

時系列の本数から見ます。ラベルにIDやパスのような値が入っていると、組み合わせの数だけ本数が増える。次にスクレイプ間隔、最後に保持期間です。rate(prometheus_tsdb_head_samples_appended_total[5m]) で毎秒のサンプル数を実測し、見積り式に入れて効果を先に計算してから手を入れると空振りしません。

Grafanaは必須ですか?

必須ではありません。9090番のUIでPromQLを実行してグラフを描けるため、まず動かして確認する段階では本体だけで足ります。ダッシュボードとして固定し、複数人で共有する段になってから足す順で構いません。

古いデータを長期保存したいときはどうしますか?

remote writeでリモートストレージへ出します。ローカルストレージは冗長化されないと公式に書かれており、1台のディスクを増やす方向では限界が来る。PromQLの評価はPrometheus側で行われるため、外へ出してもクエリ負荷は残ります。保持期間の既定15日を延ばす前に、どのメトリクスを何か月持つ必要があるかを絞り込むほうが効きます。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

ほか 13 件の記事からもリンクされています。

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.07.21 テックブログ Apache Tomcatの脆弱性一覧【2026年10月】最新版11.0.27・10.1.61・9.0.123とCVE-2026-59083ほかの影響確認・対応手順
  2. 2026.10.22 テックブログ Tomcatバージョン一覧とサポート期限【2026年10月】9.0系は2027年3月末で終了・9.1系と11.0系への移行判断
  3. 2026.10.21 テックブログ NEC委託先の不正アクセスとは|顧客システム暗号化・情報漏えいの経緯と委託元が点検する正規アカウント
  4. 2026.10.21 テックブログ ふるさとチョイス不正アクセスで445万件流出:対象確認・パスワード変更と再開時期
  5. 2026.10.23 テックブログ Renta!不正アクセスでサービス停止:再開未定の現状と運営側の停止判断・証拠保全・段階的再開

RELATED POSTS 関連記事

目次