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-сервер жив.
|
||||
Остановка: отмена подключения, остановка воркера (задания в работе отменяются), закрытие NATS и S3.
|
||||
- Объекты lifespan доступны в `app.state`: `worker`, `nats`, `storage`, `normalizer`, `health`.
|
||||
- При импорте модуля — `setup_logger` (без значений локальных переменных в трейсбеках), затем `app = create_app()`.
|
||||
- `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.exception_handlers import register_exception_handlers
|
||||
from src.core.health import HealthProvider
|
||||
from src.core.logger import setup_logger
|
||||
from src.core.nats import NatsGateway
|
||||
from src.core.worker import Worker
|
||||
from src.gateway import create_hotfolder
|
||||
@ -116,4 +118,7 @@ def create_app(settings: Settings | None = None) -> FastAPI:
|
||||
return app
|
||||
|
||||
|
||||
# Свой обработчик loguru вместо стандартного: diagnose=False — значения локальных переменных не попадают в
|
||||
# трейсбеки (#18)
|
||||
setup_logger(level="DEBUG" if get_settings().DEBUG else "INFO")
|
||||
app = create_app()
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
воркер). NATS и S3 не нужны: в тестах lifespan `NATS_ENABLED=false` либо методы `NatsGateway` подменены."""
|
||||
|
||||
import asyncio
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
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:
|
||||
app = create_app(get_settings().model_copy(update={"SCAN_HOTFOLDER_PATH": "."}))
|
||||
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