Merge pull request 'Логгер: вызывать setup_logger при импорте приложения (#63)' (#65) from feat/63-logger-diagnose into main
Reviewed-on: #65
This commit is contained in:
commit
631a80d533
@ -13,7 +13,8 @@ middleware не подключается), healthcheck (uptime, version, nats: o
|
|||||||
`recognition.result` (ack и результаты сервисов) обрабатывает inbox `handle_message` того же модуля с фабрикой сессий
|
`recognition.result` (ack и результаты сервисов) обрабатывает inbox `handle_message` того же модуля с фабрикой сессий
|
||||||
приложения (inbox меняет задание и статус файла; маппинг результата в доменные таблицы — отдельный цикл, Срез 2c D-1).
|
приложения (inbox меняет задание и статус файла; маппинг результата в доменные таблицы — отдельный цикл, Срез 2c D-1).
|
||||||
Остановка: фоновые задачи обмена → NATS → S3 → SMB → пул соединений БД; каждый шаг независим — ошибка одного
|
Остановка: фоновые задачи обмена → NATS → S3 → SMB → пул соединений БД; каждый шаг независим — ошибка одного
|
||||||
логируется и не отменяет остальные.
|
логируется и не отменяет остальные. Логгер настраивает `setup_logger` при импорте модуля: без значений локальных
|
||||||
|
переменных в трейсбеках (#63).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
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.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.logger import setup_logger
|
||||||
from src.core.nats import MessageHandler, NatsConnection
|
from src.core.nats import MessageHandler, NatsConnection
|
||||||
from src.db.db import async_session_maker, engine, session_transaction
|
from src.db.db import async_session_maker, engine, session_transaction
|
||||||
from src.services.recognition_exchange import ExchangeTasks, handle_message
|
from src.services.recognition_exchange import ExchangeTasks, handle_message
|
||||||
@ -51,6 +53,10 @@ settings = get_settings()
|
|||||||
VERSION = settings.VERSION
|
VERSION = settings.VERSION
|
||||||
UP_TIME = datetime.now(UTC)
|
UP_TIME = datetime.now(UTC)
|
||||||
|
|
||||||
|
# Свой обработчик loguru вместо стандартного: diagnose=False — значения локальных переменных не попадают в
|
||||||
|
# трейсбеки (#63)
|
||||||
|
setup_logger(level="DEBUG" if settings.DEBUG else "INFO")
|
||||||
|
|
||||||
|
|
||||||
# --- РАИСА: защищённый API (только вне DEBUG) ---------------------------------------------------
|
# --- РАИСА: защищённый API (только вне DEBUG) ---------------------------------------------------
|
||||||
protected_middleware_available = False
|
protected_middleware_available = False
|
||||||
|
|||||||
@ -5,8 +5,11 @@
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import importlib
|
import importlib
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
|
from pathlib import Path
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
from typing import Any
|
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:
|
def test_forwarded_allow_ips_default_is_loopback() -> None:
|
||||||
assert Settings.model_fields["FORWARDED_ALLOW_IPS"].default == "127.0.0.1"
|
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