|
1 | 1 | # -*- coding: utf-8 -*- |
2 | | -import logging |
3 | | -import functools |
4 | 2 | import asyncio # Import asyncio if not already present |
| 3 | +import functools |
| 4 | +import logging |
| 5 | + |
| 6 | +import structlog |
| 7 | +from structlog.stdlib import LoggerFactory, add_log_level |
| 8 | +from structlog.types import BindableLogger |
| 9 | +from twirp.context import Context as TwirpContext |
5 | 10 |
|
6 | 11 | from getstream.common import telemetry |
7 | 12 | from getstream.video.rtc.pb.stream.video.sfu.models import models_pb2 |
|
13 | 18 | logger = logging.getLogger(__name__) |
14 | 19 |
|
15 | 20 |
|
| 21 | +def _get_twirp_default_logger() -> BindableLogger: |
| 22 | + """Re-generate the default structlog config used inside `twirp` without overriding |
| 23 | + the root logger level. |
| 24 | + A trimmed down copy of `twirp.logging.configure`""" |
| 25 | + |
| 26 | + structlog.configure( |
| 27 | + logger_factory=LoggerFactory(), |
| 28 | + processors=[ |
| 29 | + add_log_level, |
| 30 | + # Add timestamp |
| 31 | + structlog.processors.TimeStamper("iso"), |
| 32 | + # Add stack information |
| 33 | + structlog.processors.StackInfoRenderer(), |
| 34 | + # Set exception field using exec info |
| 35 | + structlog.processors.format_exc_info, |
| 36 | + # Render event_dict as JSON |
| 37 | + structlog.processors.JSONRenderer(), |
| 38 | + ], |
| 39 | + ) |
| 40 | + return structlog.get_logger() |
| 41 | + |
| 42 | + |
| 43 | +_TWIRP_DEFAULT_LOGGER = _get_twirp_default_logger() |
| 44 | + |
| 45 | + |
| 46 | +class Context(TwirpContext): |
| 47 | + """A wrapper around `twirp.context.Context` to fix the logging issue. |
| 48 | + Use it as a replacement. |
| 49 | + """ |
| 50 | + |
| 51 | + def __init__(self, *args, headers=None): |
| 52 | + # Passing our own logger here because twirp configures the root logger |
| 53 | + # under the hood, making every other library noisy. |
| 54 | + super().__init__(*args, logger=_TWIRP_DEFAULT_LOGGER, headers=headers) |
| 55 | + |
| 56 | + |
16 | 57 | # Define a custom exception for SFU RPC errors |
17 | 58 | class SfuRpcError(Exception): |
18 | 59 | """Exception raised when an SFU RPC call returns an error.""" |
@@ -137,4 +178,5 @@ async def wrapped_method(*args, **kwargs): |
137 | 178 | __all__ = [ |
138 | 179 | "SfuRpcError", |
139 | 180 | "SignalClient", |
| 181 | + "Context", |
140 | 182 | ] |
0 commit comments