Skip to content

Commit a36ce45

Browse files
committed
Add mechanism to intercept third party std logging
1 parent 9abf0a6 commit a36ce45

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

src/fastcs/logging/__init__.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import logging
2+
13
from loguru import logger as _logger
24

35
from ._graylog import GraylogEndpoint as GraylogEndpoint
@@ -84,3 +86,28 @@ def configure_logging(
8486

8587
# Configure logger with defaults - INFO level and disabled
8688
configure_logging()
89+
90+
91+
class _StdLoggingInterceptHandler(logging.Handler):
92+
"""A std logging handler to forward messages to loguru with nice formatting."""
93+
94+
def emit(self, record: logging.LogRecord):
95+
logger.bind(logger_name=self.name).log(record.levelname, record.getMessage())
96+
97+
98+
def intercept_std_logger(logger_name: str):
99+
"""Intercept std logging messages from the given logger
100+
101+
To find the correct ``logger_name`` for a message. Add a breakpoint in
102+
``logging.Logger.callHandlers``, debug and run until the log message appears as
103+
``record.msg``. The logger name will be in ``self.name``.
104+
105+
:param logger_name: Name of the logger to intercept
106+
107+
"""
108+
handler = _StdLoggingInterceptHandler()
109+
handler.set_name(logger_name)
110+
111+
std_logger = logging.getLogger(logger_name)
112+
std_logger.handlers = [handler]
113+
std_logger.propagate = False

src/fastcs/transport/graphql/graphql.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from fastcs.attributes import AttrR, AttrRW, AttrW, T
1111
from fastcs.controller_api import ControllerAPI
1212
from fastcs.exceptions import FastCSError
13+
from fastcs.logging import intercept_std_logger
1314

1415
from .options import GraphQLServerOptions
1516

@@ -41,6 +42,10 @@ async def serve(self, options: GraphQLServerOptions | None = None) -> None:
4142
log_level=options.log_level,
4243
)
4344
)
45+
intercept_std_logger("uvicorn.error")
46+
intercept_std_logger("uvicorn.access")
47+
intercept_std_logger("uvicorn.asgi")
48+
4449
await self._server.serve()
4550

4651

src/fastcs/transport/rest/rest.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from fastcs.attributes import AttrR, AttrRW, AttrW, T
99
from fastcs.controller_api import ControllerAPI
1010
from fastcs.cs_methods import CommandCallback
11+
from fastcs.logging import intercept_std_logger
1112

1213
from .options import RestServerOptions
1314
from .util import (
@@ -44,6 +45,10 @@ async def serve(self, options: RestServerOptions | None):
4445
log_level=options.log_level,
4546
)
4647
)
48+
intercept_std_logger("uvicorn.error")
49+
intercept_std_logger("uvicorn.access")
50+
intercept_std_logger("uvicorn.asgi")
51+
4752
await self._server.serve()
4853

4954

0 commit comments

Comments
 (0)