diff --git a/Pipfile b/Pipfile index 7bb2de3..6dcee8a 100644 --- a/Pipfile +++ b/Pipfile @@ -17,6 +17,7 @@ uvicorn = ">=0.13,<1" orjson = ">=3.4.7,<4" pyjwt = ">=2.0.1,<3" pyyaml = ">=5.3.1,<6" +timing-asgi = ">=0.2.1,<1" [requires] python_version = "3.8" diff --git a/halfapi/app.py b/halfapi/app.py index f12aa0e..c3fc2d0 100644 --- a/halfapi/app.py +++ b/halfapi/app.py @@ -18,11 +18,14 @@ from starlette.middleware import Middleware from starlette.routing import Route from starlette.middleware.authentication import AuthenticationMiddleware +from timing_asgi import TimingMiddleware +from timing_asgi.integrations import StarletteScopeToName # module libraries from halfapi.conf import config, SECRET, PRODUCTION, DOMAINSDICT from .lib.domain_middleware import DomainMiddleware +from .lib.timing import HTimingClient from halfapi.lib.jwt_middleware import JWTAuthenticationBackend @@ -70,3 +73,11 @@ application = Starlette( 501: NotImplementedResponse } ) + +if not PRODUCTION: + application.add_middleware( + TimingMiddleware, + client=HTimingClient(), + metric_namer=StarletteScopeToName(prefix="halfapi", + starlette_app=application) + ) diff --git a/halfapi/lib/timing.py b/halfapi/lib/timing.py new file mode 100644 index 0000000..5580d13 --- /dev/null +++ b/halfapi/lib/timing.py @@ -0,0 +1,17 @@ +import logging + +from timing_asgi import TimingClient + +logger = logging.getLogger('uvicorn.asgi') + +class HTimingClient(TimingClient): + def timing(self, metric_name, timing, tags): + tags_d = { + key: val + for key, val in map( + lambda elt: elt.split(':'), tags) + } + logger.debug('[TIME:%s][%s] %s %s - %sms', + tags_d['time'], metric_name, + tags_d['http_method'], tags_d['http_status'], + round(timing*1000, 2)) diff --git a/setup.py b/setup.py index 6af5970..1cac10e 100755 --- a/setup.py +++ b/setup.py @@ -48,7 +48,8 @@ setup( "click>=7.1,<8", "uvicorn>=0.13,<1", "orjson>=3.4.7,<4", - "pyyaml>=5.3.1,<6" + "pyyaml>=5.3.1,<6", + "timing-asgi>=0.2.1,<1" ], extras_require={ "tests":[