Skip to content

Commit db75470

Browse files
Aiohttp server wrapper (#1131)
Co-authored-by: Alex Hall <[email protected]>
1 parent 2ed482d commit db75470

File tree

17 files changed

+180
-9
lines changed

17 files changed

+180
-9
lines changed

docs/integrations/http-clients/aiohttp.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ integration: otel
88

99
The [`logfire.instrument_aiohttp_client()`][logfire.Logfire.instrument_aiohttp_client] method will create a span for every request made by your AIOHTTP clients.
1010

11-
!!! question "What about AIOHTTP Server?"
12-
The AIOHTTP server instrumentation is not supported yet. You can track the progress [here][aiohttp-server].
11+
For AIOHTTP server instrumentation, see [here](../web-frameworks/aiohttp.md).
1312

1413
## Installation
1514

16-
Install `logfire` with the `aiohttp` extra:
15+
Install `logfire` with the `aiohttp-client` extra:
1716

18-
{{ install_logfire(extras=['aiohttp']) }}
17+
{{ install_logfire(extras=['aiohttp-client']) }}
1918

2019
## Usage
2120

@@ -59,5 +58,4 @@ logfire.instrument_aiohttp_client(url_filter=mask_url)
5958
```
6059

6160
[aiohttp]: https://docs.aiohttp.org/en/stable/
62-
[aiohttp-server]: https://github.com/open-telemetry/opentelemetry-python-contrib/issues/501
6361
[opentelemetry-aiohttp]: https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/aiohttp_client/aiohttp_client.html
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
integration: otel
3+
---
4+
5+
# AIOHTTP Server
6+
7+
[AIOHTTP][aiohttp] is an asynchronous HTTP client/server framework for asyncio and Python.
8+
9+
The [`logfire.instrument_aiohttp_server()`][logfire.Logfire.instrument_aiohttp_server] method will create a span for every request made to your AIOHTTP server.
10+
11+
For AIOHTTP client instrumentation, see [here](../http-clients/aiohttp.md).
12+
13+
## Installation
14+
15+
Install `logfire` with the `aiohttp-server` extra:
16+
17+
{{ install_logfire(extras=['aiohttp-server']) }}
18+
19+
## Usage
20+
21+
Here's a minimal server example:
22+
23+
```py title="server.py"
24+
import logfire
25+
from aiohttp import web
26+
27+
28+
logfire.configure()
29+
logfire.instrument_aiohttp_server()
30+
31+
32+
async def hello(request):
33+
return web.Response(text="Hello, World!")
34+
35+
36+
async def user_handler(request):
37+
user_id = request.match_info['user_id']
38+
return web.json_response({"user_id": user_id, "message": "User profile"})
39+
40+
41+
app = web.Application()
42+
app.router.add_get('/', hello)
43+
app.router.add_get('/users/{user_id}', user_handler)
44+
45+
46+
if __name__ == "__main__":
47+
web.run_app(app, host='localhost', port=8080)
48+
```
49+
50+
You can run this server with `python server.py` and then make requests to `http://localhost:8080/` or `http://localhost:8080/users/123` to see the spans created for each request.
51+
52+
The keyword arguments of [`logfire.instrument_aiohttp_server()`][logfire.Logfire.instrument_aiohttp_server] are passed to the `AioHttpServerInstrumentor().instrument()` method of the [OpenTelemetry AIOHTTP server instrumentation package](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/aiohttp_server/aiohttp_server.html).
53+
54+
[aiohttp]: https://docs.aiohttp.org/en/stable/

docs/integrations/web-frameworks/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ If you're using one of the following libraries, check out the integration docs:
1010
- [Starlette](../web-frameworks/starlette.md)
1111
- [Django](../web-frameworks/django.md)
1212
- [Flask](../web-frameworks/flask.md)
13+
- [AIOHTTP](../web-frameworks/aiohttp.md)
1314

1415
Otherwise, check if your server uses [WSGI](../web-frameworks/wsgi.md) or [ASGI](../web-frameworks/asgi.md) and check the corresponding integration.
1516

docs/plugins/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ def integrations_metadata(markdown: str, page: Page) -> str:
156156
'starlette': 'https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/starlette/starlette.html',
157157
'asgi': 'https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/asgi/asgi.html',
158158
'wsgi': 'https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/wsgi/wsgi.html',
159+
'aiohttp': 'https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/aiohttp_server/aiohttp_server.html',
159160
}
160161

161162

logfire-api/logfire_api/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ def instrument_openai_agents(self, *args, **kwargs) -> None: ...
148148

149149
def instrument_aiohttp_client(self, *args, **kwargs) -> None: ...
150150

151+
def instrument_aiohttp_server(self, *args, **kwargs) -> None: ...
152+
151153
def instrument_system_metrics(self, *args, **kwargs) -> None: ...
152154

153155
def instrument_mcp(self, *args, **kwargs) -> None: ...
@@ -189,6 +191,7 @@ def shutdown(self, *args, **kwargs) -> None: ...
189191
instrument_flask = DEFAULT_LOGFIRE_INSTANCE.instrument_flask
190192
instrument_starlette = DEFAULT_LOGFIRE_INSTANCE.instrument_starlette
191193
instrument_aiohttp_client = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_client
194+
instrument_aiohttp_server = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_server
192195
instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
193196
instrument_sqlite3 = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlite3
194197
instrument_aws_lambda = DEFAULT_LOGFIRE_INSTANCE.instrument_aws_lambda

logfire-api/logfire_api/__init__.pyi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ from .version import VERSION as VERSION
1313
from logfire.sampling import SamplingOptions as SamplingOptions
1414
from typing import Any
1515

16-
__all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'AdvancedOptions', 'ConsoleOptions', 'CodeSource', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'warning', 'error', 'exception', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_asgi', 'instrument_wsgi', 'instrument_pydantic', 'instrument_pydantic_ai', 'instrument_fastapi', 'instrument_openai', 'instrument_openai_agents', 'instrument_anthropic', 'instrument_asyncpg', 'instrument_httpx', 'instrument_celery', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_aiohttp_client', 'instrument_sqlalchemy', 'instrument_sqlite3', 'instrument_aws_lambda', 'instrument_redis', 'instrument_pymongo', 'instrument_mysql', 'instrument_system_metrics', 'instrument_mcp', 'AutoTraceModule', 'with_tags', 'with_settings', 'suppress_scopes', 'shutdown', 'no_auto_trace', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'add_non_user_code_prefix', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'loguru_handler', 'SamplingOptions', 'MetricsOptions', 'logfire_info']
16+
__all__ = ['Logfire', 'LogfireSpan', 'LevelName', 'AdvancedOptions', 'ConsoleOptions', 'CodeSource', 'PydanticPlugin', 'configure', 'span', 'instrument', 'log', 'trace', 'debug', 'notice', 'info', 'warn', 'warning', 'error', 'exception', 'fatal', 'force_flush', 'log_slow_async_callbacks', 'install_auto_tracing', 'instrument_asgi', 'instrument_wsgi', 'instrument_pydantic', 'instrument_pydantic_ai', 'instrument_fastapi', 'instrument_openai', 'instrument_openai_agents', 'instrument_anthropic', 'instrument_asyncpg', 'instrument_httpx', 'instrument_celery', 'instrument_requests', 'instrument_psycopg', 'instrument_django', 'instrument_flask', 'instrument_starlette', 'instrument_aiohttp_client', 'instrument_aiohttp_server','instrument_sqlalchemy', 'instrument_sqlite3', 'instrument_aws_lambda', 'instrument_redis', 'instrument_pymongo', 'instrument_mysql', 'instrument_system_metrics', 'instrument_mcp', 'AutoTraceModule', 'with_tags', 'with_settings', 'suppress_scopes', 'shutdown', 'no_auto_trace', 'ScrubMatch', 'ScrubbingOptions', 'VERSION', 'add_non_user_code_prefix', 'suppress_instrumentation', 'StructlogProcessor', 'LogfireLoggingHandler', 'loguru_handler', 'SamplingOptions', 'MetricsOptions', 'logfire_info']
1717

1818
DEFAULT_LOGFIRE_INSTANCE = Logfire()
1919
span = DEFAULT_LOGFIRE_INSTANCE.span
@@ -38,6 +38,7 @@ instrument_django = DEFAULT_LOGFIRE_INSTANCE.instrument_django
3838
instrument_flask = DEFAULT_LOGFIRE_INSTANCE.instrument_flask
3939
instrument_starlette = DEFAULT_LOGFIRE_INSTANCE.instrument_starlette
4040
instrument_aiohttp_client = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_client
41+
instrument_aiohttp_server = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_server
4142
instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
4243
instrument_sqlite3 = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlite3
4344
instrument_aws_lambda = DEFAULT_LOGFIRE_INSTANCE.instrument_aws_lambda
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from logfire import Logfire as Logfire
2+
from typing import Any
3+
4+
def instrument_aiohttp_server(logfire_instance: Logfire, **kwargs: Any):
5+
"""Instrument the `aiohttp` module so that spans are automatically created for each server request.
6+
7+
See the `Logfire.instrument_aiohttp_server` method for details.
8+
"""

logfire-api/logfire_api/_internal/main.pyi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,13 @@ class Logfire:
727727
[OpenTelemetry aiohttp client Instrumentation](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/aiohttp_client/aiohttp_client.html)
728728
library, specifically `AioHttpClientInstrumentor().instrument()`, to which it passes `**kwargs`.
729729
"""
730+
def instrument_aiohttp_server(self, **kwargs: Any) -> None:
731+
"""Instrument the `aiohttp` module so that spans are automatically created for each server request.
732+
733+
Uses the
734+
[OpenTelemetry aiohttp server Instrumentation](https://opentelemetry-python-contrib.readthedocs.io/en/latest/instrumentation/aiohttp_server/aiohttp_server.html)
735+
library, specifically `AioHttpServerInstrumentor().instrument()`, to which it passes `**kwargs`.
736+
"""
730737
def instrument_sqlalchemy(self, engine: AsyncEngine | Engine | None = None, enable_commenter: bool = False, commenter_options: SQLAlchemyCommenterOptions | None = None, **kwargs: Any) -> None:
731738
"""Instrument the `sqlalchemy` module so that spans are automatically created for each query.
732739

logfire/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
instrument_flask = DEFAULT_LOGFIRE_INSTANCE.instrument_flask
4343
instrument_starlette = DEFAULT_LOGFIRE_INSTANCE.instrument_starlette
4444
instrument_aiohttp_client = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_client
45+
instrument_aiohttp_server = DEFAULT_LOGFIRE_INSTANCE.instrument_aiohttp_server
4546
instrument_sqlalchemy = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlalchemy
4647
instrument_sqlite3 = DEFAULT_LOGFIRE_INSTANCE.instrument_sqlite3
4748
instrument_aws_lambda = DEFAULT_LOGFIRE_INSTANCE.instrument_aws_lambda
@@ -132,6 +133,7 @@ def loguru_handler() -> Any:
132133
'instrument_flask',
133134
'instrument_starlette',
134135
'instrument_aiohttp_client',
136+
'instrument_aiohttp_server',
135137
'instrument_sqlalchemy',
136138
'instrument_sqlite3',
137139
'instrument_aws_lambda',

logfire/_internal/integrations/aiohttp_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
raise RuntimeError(
77
'`logfire.instrument_aiohttp_client()` requires the `opentelemetry-instrumentation-aiohttp-client` package.\n'
88
'You can install this with:\n'
9-
" pip install 'logfire[aiohttp]'"
9+
" pip install 'logfire[aiohttp-client]'"
1010
)
1111
from logfire import Logfire
1212

0 commit comments

Comments
 (0)