Merge pull request 'Логгер: вызывать setup_logger при импорте приложения (#18)' (#20) from feat/18-logger-diagnose into main
Reviewed-on: #20
This commit is contained in:
commit
1e7027ba73
@ -10,6 +10,7 @@
|
|||||||
HTTP-сервер жив.
|
HTTP-сервер жив.
|
||||||
Остановка: отмена подключения, остановка воркера (задания в работе отменяются), закрытие NATS и S3.
|
Остановка: отмена подключения, остановка воркера (задания в работе отменяются), закрытие NATS и S3.
|
||||||
- Объекты lifespan доступны в `app.state`: `worker`, `nats`, `storage`, `normalizer`, `health`.
|
- Объекты lifespan доступны в `app.state`: `worker`, `nats`, `storage`, `normalizer`, `health`.
|
||||||
|
- При импорте модуля — `setup_logger` (без значений локальных переменных в трейсбеках), затем `app = create_app()`.
|
||||||
- `NATS_ENABLED=false` — подключения нет (`nats = disabled`), воркер запросов не получает (dev без NATS).
|
- `NATS_ENABLED=false` — подключения нет (`nats = disabled`), воркер запросов не получает (dev без NATS).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ from src.core.clients import S3Storage
|
|||||||
from src.core.config import Settings, get_settings
|
from src.core.config import Settings, get_settings
|
||||||
from src.core.exception_handlers import register_exception_handlers
|
from src.core.exception_handlers import register_exception_handlers
|
||||||
from src.core.health import HealthProvider
|
from src.core.health import HealthProvider
|
||||||
|
from src.core.logger import setup_logger
|
||||||
from src.core.nats import NatsGateway
|
from src.core.nats import NatsGateway
|
||||||
from src.core.worker import Worker
|
from src.core.worker import Worker
|
||||||
from src.gateway import create_hotfolder
|
from src.gateway import create_hotfolder
|
||||||
@ -116,4 +118,7 @@ def create_app(settings: Settings | None = None) -> FastAPI:
|
|||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
# Свой обработчик loguru вместо стандартного: diagnose=False — значения локальных переменных не попадают в
|
||||||
|
# трейсбеки (#18)
|
||||||
|
setup_logger(level="DEBUG" if get_settings().DEBUG else "INFO")
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
воркер). NATS и S3 не нужны: в тестах lifespan `NATS_ENABLED=false` либо методы `NatsGateway` подменены."""
|
воркер). NATS и S3 не нужны: в тестах lifespan `NATS_ENABLED=false` либо методы `NatsGateway` подменены."""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
@ -228,3 +230,48 @@ def test_create_app_fails_on_broken_rules(tmp_path: Path) -> None:
|
|||||||
def test_create_app_uses_ocr_normalizer() -> None:
|
def test_create_app_uses_ocr_normalizer() -> None:
|
||||||
app = create_app(get_settings().model_copy(update={"SCAN_HOTFOLDER_PATH": "."}))
|
app = create_app(get_settings().model_copy(update={"SCAN_HOTFOLDER_PATH": "."}))
|
||||||
assert isinstance(app.state.normalizer, OcrNormalizer)
|
assert isinstance(app.state.normalizer, OcrNormalizer)
|
||||||
|
|
||||||
|
|
||||||
|
# --- Логгер: значения локальных переменных не попадают в лог (#18) ----------------------------------------------------
|
||||||
|
|
||||||
|
_LOG_EXCEPTION_SCRIPT = """
|
||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from loguru import logger
|
||||||
|
|
||||||
|
sys.path.insert(0, os.getcwd())
|
||||||
|
importlib.import_module("src.app")
|
||||||
|
|
||||||
|
|
||||||
|
def fail():
|
||||||
|
secret = "local-secret-value"
|
||||||
|
raise ValueError("boom" if secret else "")
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
fail()
|
||||||
|
except ValueError:
|
||||||
|
logger.exception("ошибка")
|
||||||
|
logger.complete()
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_app_import_logs_exceptions_without_local_values(tmp_path: Path) -> None:
|
||||||
|
"""Импорт приложения настраивает loguru через setup_logger (diagnose=False): трейсбек есть, значений локальных
|
||||||
|
переменных в нём нет. Отдельный процесс — тесты перенастраивают обработчики loguru, здесь нужен чистый импорт.
|
||||||
|
Скрипт — файлом: без исходника (`python -c`) loguru не аннотирует строки и тест прошёл бы и с diagnose=True."""
|
||||||
|
script = tmp_path / "log_exception.py"
|
||||||
|
script.write_text(_LOG_EXCEPTION_SCRIPT)
|
||||||
|
result = subprocess.run(
|
||||||
|
[sys.executable, str(script)],
|
||||||
|
cwd=Path(__file__).resolve().parents[2],
|
||||||
|
capture_output=True,
|
||||||
|
text=True,
|
||||||
|
timeout=60,
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
output = result.stdout + result.stderr
|
||||||
|
assert "ValueError: boom" in output
|
||||||
|
assert "local-secret-value" not in output
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user