[Python] Tornadoでリクエストの処理時間を計測する

概要

Tornadoで作ったWebアプリケーションでPrometheusクライアントを使ってリクエストの処理時間を計測する方法を紹介します。

環境

この記事では、Python 3.9.1 で以下のパッケージを使って動作確認をしました。

tornado==6.1
prometheus_client==0.8.0

実装

HTTPServerRequestrequest_time()メソッドでリクエストの処理時間が取得できるので、RequestHandleron_finish()メソッドで記録します。

import tornado.ioloop
import tornado.web
from prometheus_client.metrics import Histogram
from prometheus_client.registry import REGISTRY
from prometheus_client.exposition import choose_encoder

histogram = Histogram(
    # Spring Boot Actuatorと名前を揃えておく
    name='http_server_requests_seconds',
    documentation='Latency',
    labelnames=('method', 'uri', 'status'))


class MetricsHandler(tornado.web.RequestHandler):
    def get(self):
        encoder, content_type = choose_encoder(
            self.request.headers.get('Accept'))
        self.set_header('Content-Type', content_type)
        self.write(encoder(REGISTRY))


class TestHandler(tornado.web.RequestHandler):
    def get(self) -> None:
        # ここで処理を行う
        self.write('OK')

    def on_finish(self) -> None:
        # レイテンシを記録する
        histogram.labels(
            method=self.request.method,
            uri=self.request.path,
            status=int(self.get_status())
        ).observe(self.request.request_time())


def main():
    app = tornado.web.Application([
        (r'/test', TestHandler),
        (r'/metrics', MetricsHandler),
    ])
    app.listen(8080)
    tornado.ioloop.IOLoop.current().start()


if __name__ == '__main__':
    main()

動作確認

サーバを起動して、http://localhost:8080/test, http://localhost:8080/metrics にアクセスして動作を確認します。

# レイテンシを計測する
$ curl http://localhost:8080/test
OK

# 計測結果を表示する
$ curl http://localhost:8080/metrics
...
# HELP http_server_requests_seconds Latency
# TYPE http_server_requests_seconds histogram
http_server_requests_seconds_bucket{le="0.005",method="GET",status="200",uri="/test"} 1.0 http_server_requests_seconds_bucket{le="0.01",method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_bucket{le="0.025",method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_bucket{le="0.05",method="GET",status="200",uri="/test"} 1.0 http_server_requests_seconds_bucket{le="0.075",method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_bucket{le="0.1",method="GET",status="200",uri="/test"} 1.0 http_server_requests_seconds_bucket{le="0.25",method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_bucket{le="0.5",method="GET",status="200",uri="/test"} 1.0 http_server_requests_seconds_bucket{le="0.75",method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_bucket{le="1.0",method="GET",status="200",uri="/test"} 1.0 http_server_requests_seconds_bucket{le="2.5",method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_bucket{le="5.0",method="GET",status="200",uri="/test"} 1.0 http_server_requests_seconds_bucket{le="7.5",method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_bucket{le="10.0",method="GET",status="200",uri="/test"} 1.0 http_server_requests_seconds_bucket{le="+Inf",method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_count{method="GET",status="200",uri="/test"} 1.0
http_server_requests_seconds_sum{method="GET",status="200",uri="/test"} 0.0024328231811523438
# HELP http_server_requests_seconds_created Latency
# TYPE http_server_requests_seconds_created gauge
http_server_requests_seconds_created{method="GET",status="200",uri="/test"} 1.6175342756391191e+09

参考

「[Python] Tornadoでリクエストの処理時間を計測する」への1件のフィードバック

コメントする