Skip to content

Commit 13ee25b

Browse files
доработка логирования
1 parent 7b58aae commit 13ee25b

File tree

8 files changed

+284
-109
lines changed

8 files changed

+284
-109
lines changed

docs/Логирование.md

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from fastapi_django.utils.logging import logging_context
2-
31
# Логирование
42

53
Логирование реализовано как в Django. Настройки логирования прописываются в LOGGING. Значение может быть словарем
@@ -17,13 +15,12 @@ uvicorn.run(**params, log_config=None)
1715

1816
## Контекстно зависимое логирование
1917

20-
Чтобы добавить в лог дополнительных полей, используйте контекстный менеджер `fastapi_django.utils.logging.logging_context`.
18+
Чтобы добавить в лог дополнительных полей, используйте контекстный менеджер `fastapi_django.logging.logging_context`.
2119
Пример применения:
2220

2321
```python
2422
import logging
25-
from fastapi_django.utils.logging import logging_context
26-
23+
from fastapi_django.logging import logging_context
2724

2825
with logging_context(num=1):
2926
logging.info("лог с контекстом")
@@ -39,53 +36,6 @@ logging.info("лог БЕЗ контекста")
3936
# }
4037
```
4138

42-
## Обновление контекста логирования
43-
44-
Иногда необходимо добавить в контекст логирования, но нет возможности применить контекстный менеджер. Например,
45-
при успешной аутентификации необходимо добавить информацию о пользователе (логин, идентификатор), но использования
46-
контекстного менеджера вот так:
47-
48-
```python
49-
from fastapi.security import HTTPBearer
50-
from fastapi import Request
51-
from fastapi_django.utils.logging import logging_context
52-
53-
54-
class UsrAdmAuth(HTTPBearer):
55-
56-
async def __call__(self, request: Request):
57-
# аутентификация...
58-
user = self._get_user()
59-
with logging_context(username=user.username):
60-
return user
61-
62-
async def _get_user(self) -> User:
63-
# получаем пользователя кз
64-
```
65-
66-
не сработает. Поэтому предлагается использовать функцию `fastapi_django.utils.logging.update_logging_context`.
67-
Перепишем код выше:
68-
69-
```python
70-
from fastapi.security import HTTPBearer
71-
from fastapi import Request
72-
from fastapi_django.utils.logging import update_logging_context
73-
74-
75-
class UsrAdmAuth(HTTPBearer):
76-
77-
async def __call__(self, request: Request):
78-
# аутентификация...
79-
user = self._get_user()
80-
update_logging_context(username=user.username)
81-
return user
82-
83-
async def _get_user(self) -> User:
84-
# получаем пользователя кз
85-
```
86-
87-
тогда username появится в последующих логах.
88-
8939
## Пример
9040

9141
Пример настройки LOGGING см. по ссылке https://github.com/albertalexandrov/fastapi-django-example/blob/main/src/settings.py

fastapi_django/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
def setup():
22
# последовательность действий, которые должны быть выполнены перед запуском какого-либо
33
# процесса. одним из таких действий является, например, настройка логирования
4-
from fastapi_django.utils.logging import configure_logging
4+
from fastapi_django.logging import configure_logging
55
configure_logging()

fastapi_django/conf/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ def __dir__(self):
5353
self._setup()
5454
return dir(self._wrapped)
5555

56+
def extend(self, settings_module=None):
57+
mod = importlib.import_module(settings_module)
58+
for setting in dir(mod):
59+
if setting.isupper() and not hasattr(self, setting):
60+
value = getattr(mod, setting)
61+
setattr(self, setting, value)
62+
return self
63+
5664

5765
class Settings:
5866
def __init__(self, settings_module):

fastapi_django/logging.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import logging
2+
from contextlib import contextmanager
3+
from contextvars import ContextVar
4+
from logging.config import dictConfig
5+
from typing import Any
6+
7+
from fastapi_django.conf import settings
8+
9+
# контекст логирования. когда необходимо в контекст добавляются желаемые значения,
10+
# которые затем будут доступны в LogRecord
11+
logging_context_var = ContextVar("logging_context", default={})
12+
13+
14+
def configure_logging():
15+
if settings.LOGGING:
16+
logging.config.dictConfig(settings.LOGGING)
17+
18+
19+
@contextmanager
20+
def logging_context(**kw: Any):
21+
# добавляет в контекст логирования желаемые значения
22+
current_context = logging_context_var.get()
23+
new_context = {**current_context, **kw}
24+
token = logging_context_var.set(new_context)
25+
try:
26+
yield
27+
finally:
28+
logging_context_var.reset(token)

fastapi_django/management/cli.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import uvicorn
2+
from IPython import embed
23
from typer import Typer
34

45
from fastapi_django.conf import settings
56
from fastapi_django.exceptions import ImproperlyConfigured
6-
from fastapi_django.utils.logging import get_logging_config
77

88
typer = Typer(rich_markup_mode="markdown")
99

@@ -24,7 +24,7 @@ def runserver():
2424
if (param := param.lower()) == "log_config":
2525
raise ImproperlyConfigured("Настройки логирования необходимо определять в настройке LOGGING")
2626
params[param] = getattr(settings, setting)
27-
uvicorn.run(**params, log_config=get_logging_config())
27+
uvicorn.run(**params, log_config=settings.LOGGING)
2828

2929

3030
@typer.command()
@@ -33,3 +33,11 @@ def echo(message: str):
3333
Эхо-команда
3434
"""
3535
print(f"Echo: {message}")
36+
37+
38+
@typer.command()
39+
def shell() -> None:
40+
"""
41+
Runs a Python interactive interpreter (iPython)
42+
"""
43+
embed()

fastapi_django/utils/logging.py

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)