mei_13のPython講座 ロゴ

【解説】PythonとPrometheus Client Libraryで始める、アプリケーションの「健康診断」




🐍 初心者歓迎!月額4,000円で質問し放題のPython講座
(1時間4,000円の伴走型ビデオチャット指導も受付中!)
🚀 講座の詳細を見る 📩 質問・お問い合わせ

PythonとPrometheus Client Libraryで始める、アプリケーションの「健康診断」


Yukiのアイコン
【Yuki】 Hirokiくん、こんにちは。今日は、Pythonで作ったプログラムが「今どんな状態なのか」を外から観察するための道具、Prometheus Client Libraryについてお話ししようと思います……。 大きなシステムを動かしていると、プログラムが止まっていないか、どのくらい忙しいのかを知ることは、とても大切なんです。


Hirokiのアイコン
【Hiroki】 Yukiさん、こんにちは!システムの健康診断みたいなものですね。 でも、プログラムが動いているかどうかって、ログを見ればわかるんじゃないんですか?


Yukiのアイコン
【Yuki】 そうですね、ログも大切です。でも、ログは「何が起きたか」という記録ですよね。 Prometheusが得意なのは「メトリクス」といって、数値データの積み重ねなんです。例えば、1秒間に何回リクエストが来たか、メモリを何メガバイト使っているか、といった情報をグラフで見えるようにするためのものですね。 今日はそのためのPython公式ライブラリの使い方を、ゆっくり見ていきましょう。

Prometheus Client Libraryとは


Yukiのアイコン
【Yuki】 まず、Prometheus(プロメテウス)そのものについて少しだけ触れておきますね。 Prometheusは、システムを監視して、数値データを集めるためのオープンソースのツールです。 そして、PythonのPrometheus Client Libraryは、自分の書いたPythonプログラムの中に「計測器」を設置して、Prometheusがデータを読み取れる形式で公開するためのライブラリなんです。


Hirokiのアイコン
【Hiroki】 なるほど。Python側で「今の数値はこれだよ!」って準備しておくためのものなんですね。


Yukiのアイコン
【Yuki】 はい、その通りです……。 このライブラリを使うと、たった数行で計測用のサーバーを立ち上げることができて、アプリケーションの内部状態を数値化できるんですよ。 誰かの役に立つために、そっと裏側で働き続ける小さなツールの話を聞くと、わたしも少しだけ、心が温かくなる気がします……。


Hirokiのアイコン
【Hiroki】 裏方で支える存在、かっこいいですね! まずは何を準備すればいいんでしょうか?


Yukiのアイコン
【Yuki】 まずは、ライブラリのインストールから始めましょう。 ターミナルで以下のコマンドを実行するだけです。

pip install prometheus_client


Yukiのアイコン
【Yuki】 これで準備は完了です。簡単でしょう?

4つの主要なメトリクスタイプ


Hirokiのアイコン
【Hiroki】 インストールできました! でも、数値を測るって言っても、いろんな測り方がありそうですね。


Yukiのアイコン
【Yuki】 ええ、そこがとても重要なんです。 Prometheus Client Libraryには、主に4つのメトリクスタイプがあります。 これらを使い分けることで、アプリケーションの状況を正確に表現できるようになると思います。

  1. Counter(カウンター)
  2. Gauge(ゲージ)
  3. Histogram(ヒストグラム)
  4. Summary(サマリー)

一つずつ、どんなものか見ていきましょうか……。

Counter:増え続ける値を測る


Yukiのアイコン
【Yuki】 まずは一番シンプルなCounterです。これは「増えることしかない」値を測るのに使います。 例えば、「合計リクエスト数」や「エラーが発生した回数」などですね。


Hirokiのアイコン
【Hiroki】 減ることはないもの、ということですね。


Yukiのアイコン
【Yuki】 はい。Counterは、プログラムが再起動すると0に戻りますが、基本的には右肩上がりのグラフになります。 具体的なコードを書いてみますね。

from prometheus_client import start_http_server, Counter
import time
import random

# Counterの定義:名前と説明を書きます
REQUEST_COUNT = Counter('app_requests_total', 'Total number of requests received')

def process_request():
    # リクエストを処理する代わりにCounterを増やす
    REQUEST_COUNT.inc() # 1増やす
    print("Request processed!")

if __name__ == '__main__':
    # 8000番ポートでメトリクス公開用のサーバーを起動
    start_http_server(8000)
    print("Metrics server started on port 8000")

    while True:
        process_request()
        time.sleep(random.uniform(0.1, 1.0))


Yukiのアイコン
【Yuki】 このコードを実行して、ブラウザで http://localhost:8000 にアクセスしてみてください。 すると、Prometheus形式のテキストが表示されるはずです。


Hirokiのアイコン
【Hiroki】 あ、本当だ! app_requests_total という項目の後ろに数字が出ています。 ページを更新するたびに、数字が増えていきますね。


Yukiのアイコン
【Yuki】 それがCounterの役割です。inc() メソッドを呼ぶだけで、記録が積み重なっていきます。 特定の数だけ増やしたいときは inc(5) のように引数を渡すこともできますよ。

Gauge:変動する値を測る


Yukiのアイコン
【Yuki】 次はGaugeです。これは温度計のようなもので、数値が上がったり下がったりするものを測るのに適しています。 「現在のメモリ使用量」や「実行中のスレッド数」、「キューに溜まっているタスクの数」などに向いていると思います……。


Hirokiのアイコン
【Hiroki】 さっきのCounterとは違って、減ることもあるんですね。


Yukiのアイコン
【Yuki】 はい。使い方もCounterと似ていますが、値をセットしたり、減らしたりするメソッドがあります。

from prometheus_client import Gauge

# Gaugeの定義
ACTIVE_USERS = Gauge('app_active_users', 'Number of currently active users')

# 値を直接設定する
ACTIVE_USERS.set(10)

# 値を増やす、減らす
ACTIVE_USERS.inc() # 11になる
ACTIVE_USERS.dec(2) # 9になる


Hirokiのアイコン
【Hiroki】 set() で特定の数値にできるのは便利そうです。 今の在庫数とか、そういうものにも使えそうですね!


Yukiのアイコン
【Yuki】 そうですね。今の瞬間の状態を切り取って教えてくれる、とても素直なメトリクスだと思います。

HistogramとSummary:分布を測る


Yukiのアイコン
【Yuki】 さて、ここからは少しだけ難しくなるかもしれません……。 HistogramSummaryは、主に「処理にかかった時間」などを測るために使われます。 「平均して何秒かかったか」だけでなく、「99%のリクエストが何秒以内に終わったか」という、偏り(分布)を知ることができるんです。


Hirokiのアイコン
【Hiroki】 平均だけじゃダメなんですか?


Yukiのアイコン
【Yuki】 平均だと、たった一つのすごく遅い処理が隠れてしまうことがあるんです。 例えば、ほとんどの人が0.1秒で終わっているのに、一人だけ10秒かかっていたら、サービスとしては問題ですよね。 Histogramを使うと、それを炙り出すことができます。

from prometheus_client import Histogram
import time

# Histogramの定義
REQUEST_LATENCY = Histogram('app_request_latency_seconds', 'Time spent processing request')

@REQUEST_LATENCY.time() # デコレータとして使うと、関数の実行時間を自動で測ってくれます
def slow_function():
    time.sleep(1.2)

# または with 構文でも使えます
with REQUEST_LATENCY.time():
    # 何らかの処理
    time.sleep(0.5)


Hirokiのアイコン
【Hiroki】 @REQUEST_LATENCY.time() って書くだけで測れるんですか? それはすごく便利です!


Yukiのアイコン
【Yuki】 ええ、手間がかからないよう工夫されています。 Summaryも似ていますが、計算の仕方が少し違います。 最初はHistogramを使ってみるのが一般的かもしれませんね……。

ラベルで詳細なデータをとる


Yukiのアイコン
【Yuki】 ここでもう一つ、Prometheusの強力な機能である「ラベル」についてお話しします。 例えば、リクエスト数を数える時に、それが「成功したリクエスト」なのか「失敗したリクエスト」なのかを分けて知りたいことがありますよね。


Hirokiのアイコン
【Hiroki】 はい、エラーが起きたときだけ急増してないか知りたいです。


Yukiのアイコン
【Yuki】 そういう時に、ラベルを使います。 メトリクス名を変えるのではなく、一つのメトリクスに付箋を貼るようなイメージです。

from prometheus_client import Counter

# ラベル名を指定して定義
HTTP_REQUESTS = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint', 'status'])

# ラベルの値を指定してカウント
HTTP_REQUESTS.labels(method='get', endpoint='/home', status='200').inc()
HTTP_REQUESTS.labels(method='post', endpoint='/login', status='500').inc()


Hirokiのアイコン
【Hiroki】 わあ、これなら「どの画面でエラーが出ているか」がひと目で分かりますね。


Yukiのアイコン
【Yuki】 そうなんです。でも、ラベルの種類を増やしすぎると、データの量が爆発的に増えてしまうので注意が必要です……。 例えば、ユーザーIDをラベルに入れてしまうと、ユーザーの数だけデータが作られて、Prometheusがパンクしてしまうかもしれません。 慎重に、でも効果的に使うのがコツだと思います。

実際に動かしてみよう


Hirokiのアイコン
【Hiroki】 なんとなく使い方がわかってきました。 これらを組み合わせた、実用的なサンプルを見てみたいです!


Yukiのアイコン
【Yuki】 そう言うと思って、簡単なWebサーバーを模したサンプルを用意してみました。 擬似的にエラーを発生させたり、処理時間をランダムに変えたりしています。

import time
import random
from prometheus_client import start_http_server, Counter, Histogram, Gauge

# メトリクスの定義
REQUEST_COUNT = Counter('my_app_requests_total', 'Total requests', ['method', 'status'])
LATENCY = Histogram('my_app_duration_seconds', 'Response time in seconds')
MEMORY_USAGE = Gauge('my_app_memory_usage_bytes', 'Virtual memory usage')

def simulate_app():
    # メモリ使用量のシミュレーション
    MEMORY_USAGE.set(random.randint(500, 1000) * 1024 * 1024)

    # 処理時間の計測
    with LATENCY.time():
        time.sleep(random.uniform(0.01, 0.5))

        # 成功か失敗かをランダムに決める
        if random.random() < 0.9:
            REQUEST_COUNT.labels(method='GET', status='200').inc()
        else:
            REQUEST_COUNT.labels(method='GET', status='500').inc()

if __name__ == '__main__':
    # メトリクスサーバーを8000番で起動
    start_http_server(8000)
    print("Prometheus metrics available at http://localhost:8000/metrics")

    while True:
        simulate_app()
        time.sleep(1)


Hirokiのアイコン
【Hiroki】 これを動かして、ブラウザで確認すればいいんですね。 ……あ、出てきました! my_app_duration_seconds_bucket とか、いっぱい項目が増えてます!


Yukiのアイコン
【Yuki】 Histogramを使うと、自動的にいくつかの項目が生成されるんです。 これらが集まって、綺麗なグラフになるんですよ。 わたしは夜中に静かにコードを書くのが好きなんですけど、こういう数字が規則正しく並んでいるのを見るのも、なんだか心が落ち着きます……。

集めたデータをどう使う?


Hirokiのアイコン
【Hiroki】 数値が出せるところまでは分かりました。 でも、このテキストデータを見ただけでは、あんまり「監視してる」って感じがしないですね。


Yukiのアイコン
【Yuki】 そうですよね……。このPythonプログラムは、あくまで「データを公開する場所」を作っただけなんです。 実際に活用するには、次のステップが必要です。

  1. Prometheusサーバーを立てて、このPythonプログラムのURLを見に行く(スクレイピング)ように設定する。
  2. Grafana(グラファナ)などのツールを使って、Prometheusの中にあるデータをグラフにする。


Hirokiのアイコン
【Hiroki】 なるほど。Pythonがデータを出す担当で、Prometheusがそれを回収する担当、Grafanaが見せる担当、という分担なんですね。


Yukiのアイコン
【Yuki】 その通りです。 Prometheusサーバーの設定ファイル(prometheus.yml)に、こんな風に書き加えるだけで、データの回収が始まります。

scrape_configs:
  - job_name: 'my_python_app'
    static_configs:
      - targets: ['localhost:8000']


Yukiのアイコン
【Yuki】 こうすることで、あなたの作ったプログラムが、大きな監視システムの一部として組み込まれることになります。 自分が作った小さなツールが、誰かのシステムを支える一部になれる……。 そう考えると、少しだけワクワクしませんか?


Hirokiのアイコン
【Hiroki】 はい!自分のプログラムがちゃんと動いているかいつでも見守れるのって、安心感があります。

まとめ


Yukiのアイコン
【Yuki】 今日はPythonのPrometheus Client Libraryについて解説しました。 最後に大切なポイントを振り返ってみましょうか。

  • Counterは増え続ける値に使う。
  • Gaugeは増減する現在の値に使う。
  • Histogramは処理時間などの分布に使う。
  • Labelsを使うと、詳細な分析ができる(ただし増やしすぎに注意)。
  • start_http_server() で簡単にメトリクスを公開できる。


Hirokiのアイコン
【Hiroki】 ありがとうございます! まずは自分の作ったスクリプトにCounterを入れて、何回動いたか数えるところから始めてみます。


Yukiのアイコン
【Yuki】 それは素敵な第一歩だと思います……。 もし分からないことがあったら、いつでも聞いてくださいね。 あなたが一生懸命学ぼうとしている姿を見ると、わたしも力になりたいなって、心から思います。 ……ええと、あまり見つめられると恥ずかしいので、今日はこの辺にしておきましょうか。


Hirokiのアイコン
【Hiroki】 はい、ありがとうございました、Yukiさん!


参考資料: - Prometheus Python Client (GitHub) - Prometheus Official Documentation - PyPI - prometheus-client



< Terraform
コラム一覧に戻る
ELK Stack >

この記事では基礎を解説しましたが、実務においては「もっと複雑なデータを扱いたい」「独自のシステムに組み込みたい」といった、個別の課題に直面することも多いはずです。

「自分で書く時間は最小限に抑え、プロの品質でツールを完成させたい」という方は、ぜひ一度ご相談ください。

「教わる」だけでなく「形にする」パートナーとして、フリーランスエンジニアのmei_13が最短ルートでの解決をサポートします。

➡ ココナラで制作・相談を依頼する(見積もり無料)


初心者から始められるPythonレッスン

プログラミング未経験者・初心者歓迎!
月額4,000円で質問し放題!!
● 完全オンライン
● 翌日までには必ず返信
● 挫折しない独自の学習メソッド
● 圧倒的高評価!!
テキストベースで時間を選ばない
4,000円/60分伴走型ビデオチャット指導も可能
● 高品質なサンプルコード
詳細はこちら

📩 質問・お問い合わせはこちら



AIアシスタント Yuki