25e8c9f8fc
bound_contextvars() returns a sync _GeneratorContextManager, not async. Using `async with` caused TypeError crashing all web API requests.
28 lines
942 B
Python
28 lines
942 B
Python
from __future__ import annotations
|
|
|
|
from collections.abc import Awaitable, Callable
|
|
from typing import Any
|
|
|
|
from aiogram import BaseMiddleware
|
|
from aiogram.types import TelegramObject
|
|
from structlog.contextvars import bound_contextvars
|
|
|
|
|
|
class ContextVarsMiddleware(BaseMiddleware):
|
|
"""Bind user/chat context to structlog contextvars for automatic log enrichment."""
|
|
|
|
async def __call__(
|
|
self,
|
|
handler: Callable[[TelegramObject, dict[str, Any]], Awaitable[Any]],
|
|
event: TelegramObject,
|
|
data: dict[str, Any],
|
|
) -> Any:
|
|
ctx: dict[str, Any] = {}
|
|
if hasattr(event, 'from_user') and event.from_user:
|
|
ctx['user_id'] = event.from_user.id
|
|
ctx['username'] = event.from_user.username or ''
|
|
if hasattr(event, 'chat') and event.chat:
|
|
ctx['chat_id'] = event.chat.id
|
|
with bound_contextvars(**ctx):
|
|
return await handler(event, data)
|