Skip to content

Commit 9115447

Browse files
committed
Remove direct structlog usage
1 parent 80258e3 commit 9115447

File tree

5 files changed

+34
-27
lines changed

5 files changed

+34
-27
lines changed

src/common/logs/__init__.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,22 @@
1515

1616
def init_logger(config: AppConfig) -> None:
1717
"""
18-
Configure structlog and stdlib logging with shared handler and formatter.
18+
Function to initialize logging configuration using `structlog` and Python's standard
19+
logging module. It supports dynamic log level adjustment, shared processors for
20+
structlog and standard loggers, and tailored configurations for different environments
21+
(local, test, or production). Ensures consistent formatting across application logs
22+
and integrates handlers for OpenTelemetry logs if present.
23+
24+
Args:
25+
config (AppConfig): Configuration object containing application-wide settings
26+
such as DEBUG flag and environment status.
27+
28+
Raises:
29+
None
30+
31+
Returns:
32+
None
1933
20-
:param config: The app configuration
21-
:type config: AppConfig
22-
:return:
2334
"""
2435
# Strongly inspired by https://gist.github.com/nymous/f138c7f06062b7c43c060bf03759c29e
2536

@@ -83,10 +94,9 @@ def init_logger(config: AppConfig) -> None:
8394
# In case there's a OTEL handler we keep it but remove all the others,
8495
# in case this function is called multiple times.
8596
# NOTE all the processors are not applied to OTEL logs!
86-
for l in stdlib_logger.handlers:
87-
if not isinstance(l, LoggingHandler):
88-
stdlib_logger.removeHandler(l)
89-
97+
for handler in stdlib_logger.handlers:
98+
if not isinstance(handler, LoggingHandler):
99+
stdlib_logger.removeHandler(handler)
90100

91101
# Use structlog to format logs coming from stdlib logger
92102
stdlib_logger.addHandler(stdlib_handler)

src/domains/books/_service.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import logging
12
from collections.abc import Iterable
23

34
from anyio import to_thread
45
from dependency_injector.wiring import Provide, inject
5-
from structlog import get_logger
66

77
from common.tracing import trace_function
88
from common.utils import apply_decorator_to_methods
@@ -58,8 +58,12 @@ async def book_created_event_handler(
5858
book_id: int,
5959
) -> None: # pragma: no cover
6060
# This is just an example placeholder, there's nothing to test.
61-
logger = get_logger()
62-
await logger.ainfo(f"Processed book crated event for id `{book_id}`")
61+
logging.info(
62+
"Processed book crated event`",
63+
extra={
64+
"book_id": book_id,
65+
},
66+
)
6367

6468
def _some_cpu_intensive_blocking_task(self, book: dict) -> dict:
6569
# This is just an example placeholder,

src/gateways/event.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1+
import logging
2+
13
from cloudevents_pydantic.events import CloudEvent
2-
from structlog import get_logger
34

45

56
class NullEventGateway:
67
async def emit(self, event: CloudEvent) -> None: # pragma: no cover # No need to test this
7-
logger = get_logger()
8-
await logger.ainfo(
9-
"Event emitted",
10-
cloudevent=event.model_dump(),
11-
)
8+
logging.info("Event emitted", extra={"cloudevent": event.model_dump()})

src/http_app/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import logging
12
from typing import Union
23

34
from fastapi import FastAPI, Request
45
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
56
from starlette.responses import JSONResponse
67
from starlette_prometheus import PrometheusMiddleware, metrics
7-
from structlog import get_logger
88

99
from common import AppConfig, application_init
1010
from http_app import context
@@ -62,6 +62,5 @@ async def add_exception_middleware(request: Request, call_next):
6262
try:
6363
return await call_next(request)
6464
except Exception as e:
65-
logger = get_logger(__name__)
66-
await logger.aexception(e)
65+
logging.exception(e)
6766
return JSONResponse({"error": "Internal server error"}, status_code=500)
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
from unittest.mock import AsyncMock, MagicMock, patch
1+
from unittest.mock import MagicMock, patch
22

33
from fastapi import FastAPI
44
from fastapi.testclient import TestClient
55

66

7-
@patch("http_app.get_logger")
7+
@patch("logging.exception")
88
async def test_exception_is_logged_handler_returns_500(
9-
mocked_get_logger: MagicMock,
9+
mocked_logging_exception: MagicMock,
1010
testapp: FastAPI,
1111
):
1212
my_exc = Exception("Some random exception")
@@ -15,12 +15,9 @@ async def test_exception_is_logged_handler_returns_500(
1515
async def fake_endpoint():
1616
raise my_exc
1717

18-
mocked_get_logger.return_value.aexception = AsyncMock(return_value=None)
19-
2018
ac = TestClient(app=testapp, base_url="http://test")
2119
response = ac.get("/ppp")
2220

2321
assert response.status_code == 500
2422
assert response.json() == {"error": "Internal server error"}
25-
mocked_get_logger.assert_called_once()
26-
mocked_get_logger.return_value.aexception.assert_called_once_with(my_exc)
23+
mocked_logging_exception.assert_called_once_with(my_exc)

0 commit comments

Comments
 (0)