🐱 うさねこ教室 Python と可観測性の教室

メトリクスを計装する

🐱 この章の目次

MeterProvider のセットアップ

メトリクスの計装では MeterProvider がエントリーポイントになります。 TracerProvider と同様に、Reader と Exporter を組み合わせてデータの送信先を設定します。

pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter

reader = PeriodicExportingMetricReader(OTLPMetricExporter(endpoint="http://localhost:4317"))
provider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(provider)

PeriodicExportingMetricReader はデフォルトで 60 秒ごとにメトリクスを収集・送信します。 開発時は export_interval_millis=5000 のように短い間隔に変更すると確認が容易です。

計器の種類

OTel メトリクスでは、用途に応じた 計器(Instrument) を選択します。

計器用途
Counter単調増加する累積値リクエスト数、エラー数
Histogram値の分布を記録レスポンスタイム、ペイロードサイズ
UpDownCounter増減する値アクティブ接続数、キュー長
Gaugeある時点の瞬間値CPU 使用率、メモリ使用量

計器の選択を間違えると、バックエンドでの集約が不正確になるため注意が必要です。

ビジネスメトリクスの実装

カスタムメトリクスで、ビジネス上重要な指標を計測する例を示します。

meter = metrics.get_meter(__name__)

order_counter = meter.create_counter(
    name="app.orders.created",
    description="Number of orders created",
    unit="1",
)

latency_histogram = meter.create_histogram(
    name="app.orders.processing_duration",
    description="Time to process an order",
    unit="ms",
)

def create_order(order: Order) -> None:
    start = time.time()
    # 注文処理
    process(order)
    duration_ms = (time.time() - start) * 1000
    order_counter.add(1, {"order.type": order.type})
    latency_histogram.record(duration_ms, {"order.type": order.type})

属性(ラベル)を付与することで、メトリクスを多次元で分析できます。 ただし、カーディナリティが高い属性(ユーザー ID など)を使うとバックエンドの負荷が増大するため注意してください。

Prometheus エクスポーター

Prometheus で Pull 型の収集を行う場合は、専用エクスポーターを使います。

pip install opentelemetry-exporter-prometheus
from opentelemetry.exporter.prometheus import PrometheusMetricReader
from prometheus_client import start_http_server

reader = PrometheusMetricReader()
provider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(provider)

start_http_server(9464)  # /metrics エンドポイントを公開

この構成では、Prometheus が /metrics をスクレイプしてデータを収集します。 OTel Collector 経由で送る構成と比較し、シンプルに始められる利点があります。