https://github.com/steinnes/timing-asgi
ASGI middleware to record and emit timing metrics (to something like statsd)
https://github.com/steinnes/timing-asgi
Last synced: 3 months ago
JSON representation
ASGI middleware to record and emit timing metrics (to something like statsd)
- Host: GitHub
- URL: https://github.com/steinnes/timing-asgi
- Owner: steinnes
- Created: 2019-02-05T23:53:18.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-07-18T10:19:04.000Z (almost 2 years ago)
- Last Synced: 2025-03-29T23:11:27.232Z (3 months ago)
- Language: Python
- Homepage:
- Size: 48.8 KB
- Stars: 125
- Watchers: 1
- Forks: 10
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-asgi - timing-asgi - ASGI middleware to record and emit timing metrics. (Monitoring)
README
# timing-asgi
[](https://circleci.com/gh/steinnes/timing-asgi)
[](https://pypi.org/project/timing-asgi/)
[](https://pypi.org/project/timing-asgi/)
[](https://pypi.org/project/timing-asgi/)This is a timing middleware for [ASGI](https://asgi.readthedocs.org), useful for automatic instrumentation of ASGI endpoints.
This was developed at [GRID](https://github.com/GRID-is) for use with our backend services which are built using
python and the ASGI framework [Starlette](https://starlette.io), and intended to emit metrics to [Datadog](https://www.datadoghq.com/),
a statsd-based cloud monitoring service.# ASGI version
Since 0.2.0 this middleware only supports ASGI3, if you need ASGI2 support please use version [0.1.2](https://github.com/steinnes/timing-asgi/releases/tag/v0.1.2).
# installation
```
pip install timing-asgi
```# usage
Here's an example using the Starlette ASGI framework which prints out the timing metrics..
A more realistic example which emits the timing metrics to Datadog can be found at
[https://github.com/steinnes/timing-starlette-asgi-example](https://github.com/steinnes/timing-starlette-asgi-example).```python
import logging
import uvicornfrom starlette.applications import Starlette
from starlette.responses import PlainTextResponse
from timing_asgi import TimingMiddleware, TimingClient
from timing_asgi.integrations import StarletteScopeToNameclass PrintTimings(TimingClient):
def timing(self, metric_name, timing, tags):
print(metric_name, timing, tags)app = Starlette()
@app.route("/")
def homepage(request):
return PlainTextResponse("hello world")app.add_middleware(
TimingMiddleware,
client=PrintTimings(),
metric_namer=StarletteScopeToName(prefix="myapp", starlette_app=app)
)if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
uvicorn.run(app)```
Running this example and sending some requests:
```
$ python app.py
INFO: Started server process [35895]
INFO: Waiting for application startup.
2019-03-07 11:38:01 INFO [timing_asgi.middleware:44] ASGI scope of type lifespan is not supported yet
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: ('127.0.0.1', 58668) - "GET / HTTP/1.1" 200
myapp.__main__.homepage 0.0006690025329589844 ['http_status:200', 'http_method:GET', 'time:wall']
myapp.__main__.homepage 0.0006950000000000012 ['http_status:200', 'http_method:GET', 'time:cpu']
INFO: ('127.0.0.1', 58684) - "GET /asdf HTTP/1.1" 404
myapp.asdf 0.0005478858947753906 ['http_status:404', 'http_method:GET', 'time:wall']
myapp.asdf 0.0005909999999999804 ['http_status:404', 'http_method:GET', 'time:cpu']
```