LASSIC Media らしくメディア
Prometheusでできること、メトリクス監視の仕組みと注意点
監修・編集責任者:牛尾 昭昌(株式会社LASSIC 執行役員)
この記事の結論
- Prometheusは、監視対象がHTTPで公開する数値を定期的に取りにいき、時系列として保存して、PromQLで集計とアラートの判定を行う監視の仕組みです。
- データはメトリクス名とラベルの組み合わせで区別され、Counter・Gauge・Histogram・Summaryの型に合わせてrate()などで読み解きます。
- ラベルの値を増やしすぎると時系列が膨らみ、ローカルの保存は既定で15日分なので、長く残すなら別の仕組みと組み合わせます。
※ 本記事は2026年10月時点の公式情報(省庁・公的機関、および製品やサービスを提供する事業者が公開している資料)に基づきます。
Prometheusは、サーバーやアプリケーションが出す数値(メトリクス)を集めて保存し、問い合わせとアラートに使うオープンソースの監視ツールです。Kubernetesと同じくCNCF(Cloud Native Computing Foundation)のプロジェクトで、コンテナやクラウドで動くシステムの監視で広く使われています。一方で、監視対象から値を取りにいくpull型の集め方や、ラベルでデータを区別する考え方は、従来の監視ツールに慣れた人ほど戸惑いやすいところです。
本記事では、システム開発やIT運用の担当者に向けて、Prometheusの公式ドキュメントと、実際に手元で動かした結果をもとに、Prometheusでできること、pull型で集める仕組み、データモデルとメトリクスの型、PromQLの入口、そしてつまずきやすい点を整理します。
目次
Prometheusとは
Prometheusは、もとはSoundCloudで作られたシステム監視とアラートのためのツールキットです。2012年に始まり、現在は特定の企業から独立したオープンソースのプロジェクトとして運営されています。2016年に、Kubernetesに続く2番目のプロジェクトとしてCNCFに加わりました。*1 CNCFは2018年8月9日、PrometheusがKubernetesに続いて2番目に卒業(graduation)したプロジェクトになったと発表しています。*2 卒業は、利用の広がりや運営体制が成熟したと認められた段階です。
主な特徴は、メトリクス名とラベル(キーと値の組)で時系列を区別するデータモデル、問い合わせ言語のPromQL、1台のサーバーで完結する構成、HTTPによるpull型の収集です。Prometheusサーバーのほか、計測を組み込むクライアントライブラリ、既存のソフトウェアの値を変換するエクスポーター、通知を受け持つAlertmanagerなどの部品があります。
数値の時系列を記録する用途に広く合い、マイクロサービスのように構成が頻繁に変わる環境に強みがあります。反対に、リクエストごとの課金のように1件の取りこぼしも許されない用途には向かず、課金のデータは別の仕組みで集めるよう勧めています。
pull型で集める仕組み
Prometheusは、監視対象が公開しているHTTPの窓口(多くは/metrics)へ決まった間隔でアクセスし、その時点の値を取り込みます。これをスクレイプと呼びます。取得の間隔は設定ファイルのscrape_intervalで決め、指定しなければ1分です。*3 監視対象の側は、現在の値をテキストで返すだけです。
1回の取得ごとに、Prometheusは取りにいった先を表すjob(設定したジョブ名)とinstance(ホストとポート)のラベルを自動で付け、upという時系列に結果を記録します。値は取得に成功すれば1、失敗すれば0です。*4 値が届かないことを「upが0になった」という形でそのまま検知できます。
公式のFAQは、pull型の利点として、手元のPCで監視のインスタンスを追加で立てられること、監視対象が落ちたかを判断しやすいこと、ブラウザで監視対象の状態を直接見られることを挙げます。ただし、監視システムを選ぶ際の大きな論点にすべきではないとも書いています。*5 取りにいけない短時間のバッチ処理のためには、値を預かるPushgatewayがあります。
データモデルとメトリクスの型
Prometheusが保存するデータはすべて時系列で、1本の時系列はメトリクス名と、任意のラベルの組み合わせで一意に決まります。たとえばapi_http_requests_total{method=”POST”, handler=”/messages”}は、methodとhandlerという2つのラベルを持つ時系列です。ラベルの値が1つでも変わったり、ラベルを足したり外したりすると、別の新しい時系列になります。*6 1つ1つの記録(サンプル)は、浮動小数点数の値とミリ秒単位の時刻の組です。
クライアントライブラリには4つの型があり、計測したい値の性質に合わせて選びます。
| 型 | 値の動き | 向いているもの |
|---|---|---|
| Counter | 増えるだけ。再起動で0に戻る | 処理したリクエスト数、エラーの件数 |
| Gauge | 上がりも下がりもする | メモリの使用量、同時に処理中のリクエスト数 |
| Histogram | 観測値を区間(バケット)ごとに累積で数え、合計と件数も持つ | 応答時間やレスポンスの大きさの分布 |
| Summary | アプリ側で分位数(95パーセンタイルなど)を計算して出す | 1つのプロセスの中で完結する分位数 |
Counterは増えるだけの値で、再起動したときにだけ0に戻ります。公式ドキュメントは、実行中のプロセス数のように減ることがある値にはCounterでなくGaugeを使うよう注意しています。*7 Histogramは、0.1秒以下が何件というように上限(le)ごとの累積の件数を_bucket、合計を_sum、件数を_countという時系列で出します。
具体例:Pythonで/metricsを公開する
Pythonの公式クライアントライブラリprometheus_client(今回は0.26.0)を使い、CounterとHistogramを1つずつ持つ小さなプログラムを書きました。リクエストの処理を0.01〜0.3秒の待ち時間で模し、そのうち5%を失敗(status=”500″)として数えています。start_http_serverは、計測値を返すHTTPサーバーを別のスレッドで立てる関数です。
import random
import time
from prometheus_client import Counter, Histogram, start_http_server
REQUESTS = Counter("app_requests", "処理したリクエストの数", ["method", "status"])
LATENCY = Histogram("app_request_duration_seconds", "処理にかかった秒数",
buckets=[0.05, 0.1, 0.25, 0.5])
def handle():
with LATENCY.time():
time.sleep(random.uniform(0.01, 0.3))
status = "500" if random.random() < 0.05 else "200"
REQUESTS.labels(method="GET", status=status).inc()
if __name__ == "__main__":
start_http_server(8001, addr="127.0.0.1")
while True:
handle()
起動してから手元のPCで/metricsを取得すると、次のようなテキストが返ってきました(自分で定義した2つのメトリクスの行だけを抜き出しています)。
# HELP app_requests_total 処理したリクエストの数
# TYPE app_requests_total counter
app_requests_total{method="GET",status="200"} 1972.0
app_requests_total{method="GET",status="500"} 96.0
# HELP app_request_duration_seconds 処理にかかった秒数
# TYPE app_request_duration_seconds histogram
app_request_duration_seconds_bucket{le="0.05"} 260.0
app_request_duration_seconds_bucket{le="0.1"} 610.0
app_request_duration_seconds_bucket{le="0.25"} 1684.0
app_request_duration_seconds_bucket{le="0.5"} 2064.0
app_request_duration_seconds_bucket{le="+Inf"} 2068.0
app_request_duration_seconds_count 2068.0
app_request_duration_seconds_sum 327.4334311003331
プログラムではCounterをapp_requestsと名付けましたが、出力ではapp_requests_totalになっています。prometheus_clientは、Counterを出すときに名前の末尾へ_totalを付けます。*8 Histogramは、指定した4つの上限に+Infを加えた5本の_bucketと、_sum、_countを出しています。
PromQLの入口とrate()
次に、公式の配布元(GitHubのReleases)からPrometheus 3.15.0のWindows版を取得し、上の設定で手元のプログラムを5秒ごとにスクレイプさせました。アラートルールは付属のpromtoolで書式を検査しました。
# prometheus.yml(5秒ごとに手元の /metrics を取りにいく)
global:
scrape_interval: 5s
scrape_configs:
- job_name: "demo-app"
static_configs:
- targets: ["127.0.0.1:8001"]
# アラートルールの例(エラーの割合が5%を超えた状態が10分続いたら発報)
groups:
- name: demo-app
rules:
- alert: HighErrorRatio
expr: sum(rate(app_requests_total{status="500"}[5m])) / sum(rate(app_requests_total[5m])) > 0.05
for: 10m
1分ほど集めてから、PromQLをいくつか実行した結果です。
| PromQL | 意味 | 結果 |
|---|---|---|
up |
取得に成功したか(1か0) | 1 |
rate(app_requests_total[1m]) |
直近1分の1秒あたりのリクエスト数(系列ごと) | status=”200″が約5.55、status=”500″が約0.25 |
rate(app_request_duration_seconds_sum[1m]) / rate(app_request_duration_seconds_count[1m]) |
直近1分の平均処理時間(秒) | 約0.172 |
histogram_quantile(0.95, sum by (le) (rate(app_request_duration_seconds_bucket[1m]))) |
直近1分の95パーセンタイルの推定値(秒) | 約0.457 |
count({job="demo-app"}) |
このジョブから集めている時系列の数 | 27 |
Counterの値は起動してからの累計なので、そのままでは右肩上がりの線にしかなりません。そこでrate()を使い、指定した範囲(ここでは[1m])の1秒あたりの平均の増え方を求めます。再起動でCounterが0に戻っても自動で補正されます。*9 表の2行目は、成功が1秒に約5.5件、失敗が約0.25件という意味です。
sum()のような集計と組み合わせるときは、先にrate()を取ってから集計します。先に合計すると、再起動による0への戻りを検知できなくなるためです。sum by (status) (rate(app_requests_total[1m]))のように、rate()を内側に置く形を基本にします。
アラートと保存期間
アラートは2つの部分に分かれています。Prometheusサーバーがアラートルールを評価し、条件に当てはまったアラートをAlertmanagerへ送ります。Alertmanagerは、アラートのまとめ上げ、一時的な停止(サイレンス)、関連するアラートの抑制を行い、メールやチャットなどへ通知します。*10 ルールのforは、条件に当てはまった状態がその時間続いてから発報させる指定で、一瞬だけ値がはねたときの通知を避けられます。
集めたデータは、Prometheusの中にあるローカルの時系列データベースに保存されます。保存期間は–storage.tsdb.retention.timeで決め、期間も容量の上限も指定しなければ15日です。*11 手元で起動したPrometheusでも、状態を返すAPIに15dと表示されました。データは2時間ごとのブロックにまとめられ、期限を過ぎたブロックから消えます。
つまずきやすい点
よくあるつまずきは、ラベルの値の種類(カーディナリティ)が多すぎてデータが膨らむことです。公式のベストプラクティスは、ラベルの組み合わせごとに新しい時系列ができるとして、ユーザーIDやメールアドレスのように上限の無い値をラベルにしないよう警告しています。*12 先ほどのCounterにuser_idのラベルを足して1,000人分の値を入れると、app_requests_totalの行は1,000行になりました。利用者が増えるほど時系列も増え、メモリとディスクを圧迫します。
長期の保存にも別の手当てが要ります。ローカルの保存はクラスタ化も複製もされておらず、単一ノードのデータベースと同じように扱う必要があります。そこで、外部のストレージへ書き出すremote writeと、読み戻すremote readの接続口が用意されています。何年分も残す、複数のPrometheusを横断して見るといった要件では、これに対応した長期保存の仕組みを組み合わせます。なお、NFS(AWSのEFSを含む)は保存先として対応していません。
ヒストグラムから求めた分位数は、あくまで推定値です。今回の95パーセンタイルは約0.457秒と出ましたが、待ち時間は長くても0.3秒程度に作ってあります。histogram_quantile()は、分位数が入る区間(ここでは0.25〜0.5秒)の中で観測値が均等に散らばっていると仮定して値を補うため*9、誤差はその区間の幅に左右されます。*13 SLO(サービスレベル目標)のしきい値の近くにバケットの境界を置いておくと、判定がぶれにくくなります。
ほかにも、次の点は導入の初期によく問題になります。
- Pushgatewayを常用しない:公式は、取りにいけないサービス単位のバッチ処理の結果を受ける用途に絞るよう勧めています。*141つに集めると障害時の弱点になり、upによる死活の検知も失われ、送られた値は削除するまで残ります
- ログを入れない:公式のFAQは、ログにはGrafana LokiやOpenSearchなどを使うよう答えています
- Summaryの分位数は合算できない:複数のインスタンスをまとめた95パーセンタイルが欲しいなら、Histogramで計測しておきます
ログの集約については「Grafana Lokiでログ基盤を外注構築」で扱っています。
外部に委託するときに確認しておきたい点
Prometheusの導入や運用を外部に頼むときは、何をどの単位で数えるかの設計を提案の段階で確かめます。メトリクス名とラベルの命名の決まり、ラベルに使ってよい値の範囲、バケットの境界、アラートのしきい値とforの時間、通知先です。文書で引き継がれていないと、担当が替わったときにアラートの意味を誰も説明できなくなります。
保存期間と長期保存の方針、Prometheus自身が止まったときに誰が気づくかも決めておきます。メトリクス・ログ・トレースを組み合わせた監視基盤全体の設計は「オブザーバビリティ監視基盤の構築・外注|3本柱と委託先選び」、監視SaaSの費用の見直しは「監視SaaS(Datadog等)のログ・監視コストを削減する外注の進め方」、24時間の監視体制は「システム24時間監視を外注する費用と体制の選び方」で整理しています。リクエストの流れを追うAPMやトレースは、別の仕組みと組み合わせます。
まとめ:Prometheusで確かめておきたい3つの点
Prometheusで確かめておきたい点は3つです。第一に、/metricsを決まった間隔で取りにいくpull型で、取得の成否がupに残ること。第二に、時系列はメトリクス名とラベルの組み合わせで決まり、Counterはrate()を取ってから集計すること。第三に、ラベルに上限の無い値を入れると時系列が膨らみ、ローカルの保存は既定で15日なので、長期保存は別の仕組みにつなぐことです。
よくある質問
Prometheusとあわせて使われることが多いGrafanaとは何が違いますか
Prometheusはメトリクスを集めて保存し問い合わせる側で、Grafanaはそのデータをダッシュボードで見せる可視化の道具です。公式ドキュメントも、可視化にGrafanaなどを使えると説明しています。
Prometheusを冗長化することはできますか
公式のFAQは、同じ設定のPrometheusサーバーを2台以上の別々のマシンで動かす方法を答えています。同じアラートの重複はAlertmanagerが取り除きます。
取得の間隔は短いほどよいのでしょうか
短くすると保存するサンプル数が増えます。公式のストレージの説明は、サンプルを減らすなら取得の間隔を延ばすより時系列の数を減らすほうが効果が大きいとしています。間隔は既定の1分を基準に決め、まずラベルの設計を見直します。
Prometheusによるメトリクス監視のご相談
元請(プライムベンダー)として、Prometheusを使ったメトリクス監視とアラートの設計から、システムの保守・運用までご提案します。
Remoguとリラシクなら、監視基盤の構築や、メトリクス・アラートの設計に加わるITエンジニアも探せます。
Remoguは、リモート前提で全国から即戦力のITプロ人材を調達するサービスです。リラシクは、扱う求人がすべてリモートワークのITエンジニア専門転職エージェントです。どちらもLASSICが運営しています。
出典
- *1 参考:Prometheus「Overview」(prometheus.io)(https://prometheus.io/docs/introduction/overview/)。出典:What is Prometheus?(SoundCloud、2012年、2016年にCNCFへ参加)、Features、Components、When does it fit? / When does it not fit? を参照(2026年10月確認)
- *2 参考:CNCF「Cloud Native Computing Foundation Announces Prometheus Graduation」(2018年8月9日)(https://www.cncf.io/announcements/2018/08/09/prometheus-graduates/)。出典:Kubernetesに続く2番目の卒業プロジェクトになったとの発表を参照(2026年10月確認)
- *3 参考:Prometheus「Configuration」(prometheus.io)(https://prometheus.io/docs/prometheus/latest/configuration/configuration/)。出典:global の scrape_interval(既定1m)を参照(2026年10月確認)
- *4 参考:Prometheus「Jobs and instances」(prometheus.io)(https://prometheus.io/docs/concepts/jobs_instances/)。出典:自動で付くjob・instanceのラベルと、up時系列(成功で1、失敗で0)を参照(2026年10月確認)
- *5 参考:Prometheus「FAQ」(prometheus.io)(https://prometheus.io/docs/introduction/faq/)。出典:Why do you pull rather than push?、How to feed logs into Prometheus?、Can Prometheus be made highly available? を参照(2026年10月確認)
- *6 参考:Prometheus「Data model」(prometheus.io)(https://prometheus.io/docs/concepts/data_model/)。出典:Metric names and labels(ラベルの値の変更で新しい時系列になる)、Samples、Notation を参照(2026年10月確認)
- *7 参考:Prometheus「Metric types」(prometheus.io)(https://prometheus.io/docs/concepts/metric_types/)。出典:Counter・Gauge・Histogram・Summary の説明と、サーバーが型の情報を使わない点を参照(2026年10月確認)
- *8 参考:Prometheus「client_python」(prometheus.github.io)(https://prometheus.github.io/client_python/)。出典:Instrumenting の Counter(_total の付与)・Histogram、Exporting の HTTP/HTTPS(start_http_server)を参照(2026年10月確認)
- *9 参考:Prometheus「Query functions」(prometheus.io)(https://prometheus.io/docs/prometheus/latest/querying/functions/)。出典:rate()(1秒あたりの平均の増加率、カウンターのリセットの補正、先にrate()を取ってから集計する)を参照(2026年10月確認)
- *10 参考:Prometheus「Alerting overview」(prometheus.io)(https://prometheus.io/docs/alerting/latest/overview/)。出典:アラートルールとAlertmanagerの役割分担(サイレンス、抑制、集約、通知)を参照。forの説明は同サイトの Alerting rules による(2026年10月確認)
- *11 参考:Prometheus「Storage」(prometheus.io)(https://prometheus.io/docs/prometheus/latest/storage/)。出典:On-disk layout(2時間のブロック)、Operational aspects(保存期間の既定15d、NFS非対応、取り込みサンプルの減らし方)、Remote storage integrations を参照(2026年10月確認)
- *12 参考:Prometheus「Metric and label naming」(prometheus.io)(https://prometheus.io/docs/practices/naming/)。出典:Labels の CAUTION(ラベルの組み合わせごとに新しい時系列、ユーザーIDやメールアドレスをラベルにしない)を参照(2026年10月確認)
- *13 参考:Prometheus「Histograms and summaries」(prometheus.io)(https://prometheus.io/docs/practices/histograms/)。出典:分位数の誤差がバケットの幅に左右される点、Summaryの分位数を集計できない点を参照(2026年10月確認)
- *14 参考:Prometheus「When to use the Pushgateway」(prometheus.io)(https://prometheus.io/docs/practices/pushing/)。出典:Pushgatewayを使う場面の限定と、使いすぎたときの問題点を参照(2026年10月確認)