2018年10月7日日曜日

Python の prometheus_client を使ってみた

概要

Python の prometheus_client を使ってみました
Python で開発した Web アプリに組み込むことで Prometheus 用の metrics が取得できるようになります
既存の flask アプリを想定した組み込み方法も紹介します

環境

  • macOS 10.14
  • Python 3.7.0
  • prometheus-client 0.3.1

ライブラリインストール

  • pipenv install prometheus_client

Getting Started

  • vim app.py
from prometheus_client import start_http_server, Summary
import random
import time

REQUEST_TIME = Summary('request_processing_seconds', 'Time spent processing request')

@REQUEST_TIME.time()
def process_request(t):
    time.sleep(t)

if __name__ == '__main__':
    start_http_server(8000)
    while True:
        process_request(random.random())

動作確認

  • pipenv run python3 app.py
  • curl localhost:8000

でメトリックが取得できます

# HELP python_info Python platform information
# TYPE python_info gauge
python_info{implementation="CPython",major="3",minor="7",patchlevel="0",version="3.7.0"} 1.0
# HELP request_processing_seconds Time spent processing request
# TYPE request_processing_seconds summary
request_processing_seconds_count 38.0
request_processing_seconds_sum 21.631802963

デフォルトだと python_info という名前のメトリックが実装されているようです
Summary タイプを使うと自動的にメトリック名の後ろに _count_sum を追加してメトリックを生成してくれます

既存の flask アプリにメトリックを追加する

Counter タイプのメトリックを追加してみます
flask で作ったアプリにアクセスがあった場合にアクセス数をカウントします

  • vim app1.py
from flask import Flask
from werkzeug.wsgi import DispatcherMiddleware
from werkzeug.serving import run_simple
from prometheus_client import make_wsgi_app, Counter

c = Counter('my_counter', 'Description of access counter')

app = Flask(__name__)

@app.route('/')
def index():
    return 'index'

@app.before_request
def before_request():
    c.inc()

app_dispatch = DispatcherMiddleware(app, {
    '/metrics': make_wsgi_app()
})

if __name__ == '__main__':
    run_simple('localhost', 8000, app_dispatch, use_reloader=True, use_debugger=True, use_evalex=True)

まず Counter メトリックの定義は Counter('my_counter', 'Description of access counter') でします
これだけで追加することができます
今回の場合 flask 側のアプリにアクセスがあった場合にこのカウントをインクリメント (c.inc()) します
「flask 側」という表現を使っているのは既存の flask アプリを想定しており、それに対し prometheus_client 側のアプリを追加する感じになります
アプリを追加するには flask の DispatcherMiddleware を使います
これに /metrics には prometheus_client のアプリである make_wsgi_app を設定します
prometheus_client 側のアプリは WSGI で作成されているようです
こうすることで 2 つの異なるアプリを一つのアプリとして扱うことができます

結合したアプリは run_simple を使って起動します

動作確認

  • pipenv run python3 app.py
  • curl localhost:8000/metrics

でメトリックを取得できます
カウンタを増やしたい場合は localhost:8000 にアクセスしてからメトリックを取得するとメトリックが増えていることが確認できると思います

# HELP python_info Python platform information
# TYPE python_info gauge
python_info{implementation="CPython",major="3",minor="7",patchlevel="0",version="3.7.0"} 1.0                                   
# HELP my_counter Description of access counter
# TYPE my_counter counter
my_counter 2.0

最後に

Python の prometheus_client を使ってメトリックを取得できるようにしてみました
既存の flask アプリにも追加することができました

WSGI 側のアプリを直接変更することでメトリック側のページのカウンタを作ることもできるはずですがやり方は不明です

Ruby の prometheus-client ライブラリはデフォルトでレスポンスタイムなども返してくれますが Python の場合はそうではないようです

参考サイトに記載したのですが flask であれば専用のライブラリとして公開している方がいるので最低限のメトリックでいいのであればそっちを使ったほうが無難かなと思います
内部的には今回紹介した prometheus_client を使っているので、ソースを参考にして同じように自分のアプリに組み込むこともできます

参考サイト

0 件のコメント:

コメントを投稿