fix(logger): вызывать setup_logger при импорте приложения (#63)
setup_logger() с diagnose=False существовал, но не вызывался: работал обработчик loguru по умолчанию (diagnose=True), и трейсбек любого залогированного исключения содержал значения локальных переменных. Теперь src/app.py вызывает setup_logger при импорте, как tabular-parser. Регрессионный тест в отдельном процессе: исключение с локальной переменной логируется с трейсбеком, но без её значения. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
This commit is contained in:
parent
d8bf5b22dc
commit
c937c8173f
@ -13,7 +13,8 @@ middleware не подключается), healthcheck (uptime, version, nats: o
|
||||
`recognition.result` (ack и результаты сервисов) обрабатывает inbox `handle_message` того же модуля с фабрикой сессий
|
||||
приложения (inbox меняет задание и статус файла; маппинг результата в доменные таблицы — отдельный цикл, Срез 2c D-1).
|
||||
Остановка: фоновые задачи обмена → NATS → S3 → SMB → пул соединений БД; каждый шаг независим — ошибка одного
|
||||
логируется и не отменяет остальные.
|
||||
логируется и не отменяет остальные. Логгер настраивает `setup_logger` при импорте модуля: без значений локальных
|
||||
переменных в трейсбеках (#63).
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
@ -41,6 +42,7 @@ from src.api.router import API_PREFIX, build_api_router
|
||||
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.logger import setup_logger
|
||||
from src.core.nats import MessageHandler, NatsConnection
|
||||
from src.db.db import async_session_maker, engine, session_transaction
|
||||
from src.services.recognition_exchange import ExchangeTasks, handle_message
|
||||
@ -51,6 +53,10 @@ settings = get_settings()
|
||||
VERSION = settings.VERSION
|
||||
UP_TIME = datetime.now(UTC)
|
||||
|
||||
# Свой обработчик loguru вместо стандартного: diagnose=False — значения локальных переменных не попадают в
|
||||
# трейсбеки (#63)
|
||||
setup_logger(level="DEBUG" if settings.DEBUG else "INFO")
|
||||
|
||||
|
||||
# --- РАИСА: защищённый API (только вне DEBUG) ---------------------------------------------------
|
||||
protected_middleware_available = False
|
||||
|
||||
@ -5,8 +5,11 @@
|
||||
|
||||
import asyncio
|
||||
import importlib
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
from http import HTTPStatus
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
from typing import Any
|
||||
|
||||
@ -701,3 +704,48 @@ async def test_forwarded_for_only_from_trusted_proxy(tmp_path: Any, trusted: str
|
||||
|
||||
def test_forwarded_allow_ips_default_is_loopback() -> None:
|
||||
assert Settings.model_fields["FORWARDED_ALLOW_IPS"].default == "127.0.0.1"
|
||||
|
||||
|
||||
# --- Логгер: значения локальных переменных не попадают в лог (#63) ----------------------------------------------------
|
||||
|
||||
_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[1],
|
||||
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