{"id":13598474,"url":"https://github.com/steinnes/timing-asgi","last_synced_at":"2025-04-06T01:11:25.722Z","repository":{"id":45498182,"uuid":"169331566","full_name":"steinnes/timing-asgi","owner":"steinnes","description":"ASGI middleware to record and emit timing metrics (to something like statsd)","archived":false,"fork":false,"pushed_at":"2023-07-18T10:19:04.000Z","size":50,"stargazers_count":125,"open_issues_count":3,"forks_count":10,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-29T23:11:27.232Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/steinnes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-02-05T23:53:18.000Z","updated_at":"2025-02-23T05:38:44.000Z","dependencies_parsed_at":"2024-01-16T23:26:17.938Z","dependency_job_id":"ef159334-94f9-4aa3-b9b9-494209db56cd","html_url":"https://github.com/steinnes/timing-asgi","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinnes%2Ftiming-asgi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinnes%2Ftiming-asgi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinnes%2Ftiming-asgi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/steinnes%2Ftiming-asgi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/steinnes","download_url":"https://codeload.github.com/steinnes/timing-asgi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247419863,"owners_count":20936013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T17:00:52.948Z","updated_at":"2025-04-06T01:11:25.703Z","avatar_url":"https://github.com/steinnes.png","language":"Python","funding_links":[],"categories":["Monitoring"],"sub_categories":[],"readme":"# timing-asgi\n[![CircleCI](https://circleci.com/gh/steinnes/timing-asgi.svg?style=svg\u0026circle-token=4e141ed4d7231ab6d00dc7b14624d759cf16e1d2)](https://circleci.com/gh/steinnes/timing-asgi)\n[![PyPI Downloads](https://img.shields.io/pypi/dm/timing-asgi.svg)](https://pypi.org/project/timing-asgi/)\n[![PyPI Version](https://img.shields.io/pypi/v/timing-asgi.svg)](https://pypi.org/project/timing-asgi/)\n[![License](https://img.shields.io/badge/license-mit-blue.svg)](https://pypi.org/project/timing-asgi/)\n\nThis is a timing middleware for [ASGI](https://asgi.readthedocs.org), useful for automatic instrumentation of ASGI endpoints.\n\nThis was developed at [GRID](https://github.com/GRID-is) for use with our backend services which are built using\npython and the ASGI framework [Starlette](https://starlette.io), and intended to emit metrics to [Datadog](https://www.datadoghq.com/),\na statsd-based cloud monitoring service.\n\n# ASGI version\n\nSince 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).\n\n# installation\n\n```\npip install timing-asgi\n```\n\n# usage\n\n\nHere's an example using the Starlette ASGI framework which prints out the timing metrics..\n\nA more realistic example which emits the timing metrics to Datadog can be found at\n[https://github.com/steinnes/timing-starlette-asgi-example](https://github.com/steinnes/timing-starlette-asgi-example).\n\n\n```python\nimport logging\nimport uvicorn\n\nfrom starlette.applications import Starlette\nfrom starlette.responses import PlainTextResponse\nfrom timing_asgi import TimingMiddleware, TimingClient\nfrom timing_asgi.integrations import StarletteScopeToName\n\n\nclass PrintTimings(TimingClient):\n    def timing(self, metric_name, timing, tags):\n        print(metric_name, timing, tags)\n\n\napp = Starlette()\n\n\n@app.route(\"/\")\ndef homepage(request):\n    return PlainTextResponse(\"hello world\")\n\n\napp.add_middleware(\n    TimingMiddleware,\n    client=PrintTimings(),\n    metric_namer=StarletteScopeToName(prefix=\"myapp\", starlette_app=app)\n)\n\nif __name__ == \"__main__\":\n    logging.basicConfig(level=logging.INFO)\n    uvicorn.run(app)\n\n```\n\nRunning this example and sending some requests:\n\n```\n$ python app.py\nINFO: Started server process [35895]\nINFO: Waiting for application startup.\n2019-03-07 11:38:01 INFO  [timing_asgi.middleware:44] ASGI scope of type lifespan is not supported yet\nINFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)\nINFO: ('127.0.0.1', 58668) - \"GET / HTTP/1.1\" 200\nmyapp.__main__.homepage 0.0006690025329589844 ['http_status:200', 'http_method:GET', 'time:wall']\nmyapp.__main__.homepage 0.0006950000000000012 ['http_status:200', 'http_method:GET', 'time:cpu']\nINFO: ('127.0.0.1', 58684) - \"GET /asdf HTTP/1.1\" 404\nmyapp.asdf 0.0005478858947753906 ['http_status:404', 'http_method:GET', 'time:wall']\nmyapp.asdf 0.0005909999999999804 ['http_status:404', 'http_method:GET', 'time:cpu']\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteinnes%2Ftiming-asgi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsteinnes%2Ftiming-asgi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsteinnes%2Ftiming-asgi/lists"}