メトリクスの種類と理解

はじめに

Part 3でメトリクスの4つの型を概説しました。ここからは各型を詳しく掘り下げ、どのような場面で使われるのか、実装にはどのような特徴があるのかを学びます。正しいメトリクスタイプを選ぶことは、効果的な監視設計の基本となります。

Counter(カウンター型)

特性と用途

Counterは累積的に増加する値です。HTTPリクエスト数、エラー発生回数、処理完了数など、「増える一方で減ることはない」という特性を持ちます。

Counterの重要な特徴は、値が単調増加すること。一度記録された値が過去に遡って変更されたり、値が減ったりすることはありません。ただし、アプリケーション再起動時はカウンターがリセットされる可能性がある点に注意が必要です。

実装パターン

python
from prometheus_client import Counter

# HTTPリクエスト総数を記録
http_requests_total = Counter(
    'http_requests_total',
    'Total HTTP requests',
    ['method', 'endpoint', 'status']
)

# リクエスト処理時に1をインクリメント
http_requests_total.labels(
    method='GET', endpoint='/api/users', status='200'
).inc()

クエリの実装例

promql
# 過去1分間のリクエスト増加数を計算(単位時間あたりの変化率)
rate(http_requests_total[1m])

# 特定のエンドポイントのエラー率を計算(エラー数 ÷ 全リクエスト数)
rate(http_requests_total{status="500"}[5m]) / rate(http_requests_total[5m])

Gauge(ゲージ型)

特性と用途

Gaugeは任意の値を持つメトリクス。メモリ使用率、CPU使用率、接続数、キューの深さなど、上下変動する値を記録します。

Counterと異なり、値は時間とともに上昇することも下降することもあります。現在の「状態」を表すメトリクスと考えるとわかりやすいです。

実装パターン

python
from prometheus_client import Gauge

# メモリ使用率を記録
memory_usage_bytes = Gauge(
    'memory_usage_bytes',
    'Memory usage in bytes',
    ['instance']
)

# メモリ使用率を更新
memory_usage_bytes.labels(instance='server1').set(1024 * 1024 * 512)

クエリの実装例

promql
# 現在のメモリ使用率(最新値を取得)
memory_usage_bytes

# 過去1時間のメモリ使用率の平均値
avg_over_time(memory_usage_bytes[1h])

# 複数インスタンスのメモリ使用率の合計
sum(memory_usage_bytes)

Histogram(ヒストグラム型)

特性と用途

Histogramは値の分布を記録します。HTTPリクエストのレスポンスタイム、クエリ実行時間など、「値がどのような範囲に分布しているか」を追跡したい場合に適しています。

Histogramはバケット(値の範囲)ごとに集計を行います。例えば、レスポンスタイムを「0-10ms」「10-50ms」「50-100ms」などの範囲に分類して記録します。

実装パターン

python
from prometheus_client import Histogram

# HTTPリクエストのレスポンスタイムを記録
request_duration_seconds = Histogram(
    'request_duration_seconds',
    'Request duration in seconds',
    ['endpoint'],
    buckets=(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0)
)

# リクエスト処理時間を記録
request_duration_seconds.labels(endpoint='/api/users').observe(0.234)

クエリの実装例

promql
# 95パーセンタイル(95%のリクエストがこの時間以内に完了)
histogram_quantile(0.95, rate(request_duration_seconds_bucket[5m]))

# 平均レスポンスタイム(合計時間 ÷ リクエスト数)
rate(request_duration_seconds_sum[5m]) / rate(request_duration_seconds_count[5m])

Summary(サマリー型)

特性と用途

SummaryはHistogramと同様に分布を追跡しますが、パーセンタイル値(例:50パーセンタイル、99パーセンタイル)をクライアント側で計算して保存します。

Histogramとの主な違いは、パーセンタイルの計算がクライアント側で行われるため、Prometheusサーバーの計算負荷が少なくなる点です。ただし、Summaryではレンジ指定でのパーセンタイル再計算ができません。

実装パターン

python
from prometheus_client import Summary

# データベースクエリの実行時間を記録
db_query_duration_seconds = Summary(
    'db_query_duration_seconds',
    'Database query duration in seconds',
    ['query_type'],
    quantiles=(0.5, 0.9, 0.99)
)

# クエリ実行時間を記録
db_query_duration_seconds.labels(query_type='select').observe(0.125)

4つのメトリクスタイプの比較

特性CounterGaugeHistogramSummary
値の変化単調増加のみ任意の変化分布を記録分布を記録
使用例リクエスト数、エラー数メモリ使用率、接続数レスポンスタイム実行時間(パーセンタイル)
クエリでのパーセンタイル計算不可不可可能(Histogramから計算)不可(クライアント側で計算済み)
Prometheusサーバーの負荷少ない少ない多い(バケット数に依存)少ない
ストレージ効率最も効率的効率的中程度(バケット数に依存)効率的

メトリクス設計のベストプラクティス

1. メトリクス名は明確に

http_requests_totalmemory_usage_bytes など、用途と単位が名前から推測できるようにします。単位はメトリクス名に含めるのが慣例です。例えば、時間はseconds、バイト数はbytesというように。

2. ラベルのカーディナリティに注意

ラベルに無制限に値を追加すると、メトリクスの数が爆発的に増えます。例えば、ユーザーIDを直接ラベルにするのは避け、ユーザーセグメント(例:user_type="premium")のような固定的なラベルを使います。同様に、HTTPエラーレスポンスを記録する際、詳細なエラーメッセージを直接ラベルにすると数百~数千の組み合わせが発生するため、エラーカテゴリ(例:error_type="timeout", "rate_limit")のように一般化する工夫が必要です。

3. メトリクスタイプを正しく選択

リクエスト数のようにカウント上昇するメトリクスをGaugeで記録したり、現在値であるべき値をCounterで記録すると、クエリの結果が意図しないものになります。各メトリクスの特性を理解した上で選択することが重要です。

4. 適切なバケット設定(Histogram用)

Histogramのバケット幅は、測定対象のパフォーマンス特性に合わせます。レスポンスタイムがミリ秒単位であればミリ秒単位のバケットを、秒単位であれば秒単位のバケットを設定します。粗すぎるバケットは精度を低下させ、細かすぎるバケットはストレージ効率を低下させます。

5. SummaryかHistogramか

Histogramを選ぶべき場合: SLO監視でレスポンスタイムの95パーセンタイルが100msを超えるとアラートしたい、というように、リアルタイムでパーセンタイル値を計算・再評価したい場合。Histogramなら、任意の時間帯のパーセンタイル値をPromQLで計算できます。

Summaryを選ぶべき場合: あらかじめ決められたパーセンタイル値(例:50パーセンタイル、99パーセンタイル)のみが必要で、Prometheusサーバーの計算負荷を最小化したい場合。パーセンタイル値はクライアント側で計算済みのため、サーバー側での計算が不要です。


次のステップ

ここまで、4つのメトリクスタイプを詳しく掘り下げました。次のPart 3-2では、これらのメトリクスを効果的にクエリするためのPromQL(Prometheus Query Language)を学びます。PromQLを習得することで、メトリクスから価値のある情報を引き出せるようになります。


ナビゲーション

前のパート:Part 3 - メトリクス活用・概要

次のパート:Part 3-2 - PromQL基礎・クエリ実践