B22: прикладное логирование vector.* + администрирование в доках (по образцу РВС)
- backend/logging_setup.py: setup_logging() (stdout INFO + файл /tmp/vector/vector.log,
ротация 5×2 МБ, VectorLOGLEVEL/VectorLOGFILE/VectorLOGDIR), get_logger('vector.*')
- события: vector.analyze (матрасчёт с длительностью), vector.auth (login_ok/failed/
lockout), vector.audit (каждая запись), vector.contour (ok/failed/rejected),
vector.operations (operation_complete), vector.geocode (успех/timeout/ошибка)
- существующие логгеры переведены в namespace vector.* (geo, geo.osm, rules, water, admin)
- README §13а: таблица наблюдаемых событий + правила (без ПДн/секретов)
- SETUP_GUIDE: §15 RPO/RTO + backup≠restore, §16 grep по vector.*, §17 диагностика
по цепочкам (БД, 500, fallback-зоны, вход), §17а чек-лист передачи проекта
- DEPLOY.md: вместо устаревшего дубля — ссылка на актуальные доки + шпаргалка стенда
- тесты: 239 passed
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
"""Единая настройка логирования ВЕКТОРа (B22).
|
||||
|
||||
Все модульные логгеры проекта — `logging.getLogger('vector.<модуль>')` —
|
||||
конфигурируются один раз при старте приложения (backend.main → setup_logging()).
|
||||
|
||||
Формат: время, уровень, логгер, сообщение. Вывод — stdout (контейнер),
|
||||
дополнительно файл /tmp/vector/vector.log внутри контейнера (ротация 5×2 МБ).
|
||||
|
||||
Наблюдаемые события (ключевые слова для grep по логам):
|
||||
vector.analyze — анализ: case_id, радиус, зоны, время расчёта
|
||||
vector.auth — login_ok / login_failed / lockout / logout
|
||||
vector.contour — отправка зон в КОНТУР (ok/failed)
|
||||
vector.admin — синхронизация закрытия кейса
|
||||
vector.audit — запись аудит-события (кто, что)
|
||||
vector.geo — геослой: PostGIS-режим, fallback на Overpass, ошибки
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import logging.handlers
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
_LOG_FORMAT = '%(asctime)s %(levelname)s %(name)s: %(message)s'
|
||||
_LOG_DATEFMT = '%Y-%m-%d %H:%M:%S'
|
||||
|
||||
# Порог вывода в stdout: INFO на сервере, DEBUG при VectorLOGLEVEL=debug
|
||||
_LEVEL = os.getenv('VectorLOGLEVEL', 'info').upper()
|
||||
|
||||
# Файл-хэндлер: по умолчанию включён (внутри контейнера /tmp/vector).
|
||||
_FILE_ENABLED = os.getenv('VectorLOGFILE', '1').strip().lower() not in {'0', 'false', 'no'}
|
||||
_FILE_DIR = Path(os.getenv('VectorLOGDIR', '/tmp/vector'))
|
||||
|
||||
|
||||
def setup_logging() -> None:
|
||||
"""Конфигурация корневого пакета 'vector'. Идемпотентна."""
|
||||
root = logging.getLogger('vector')
|
||||
if getattr(root, '_vector_configured', False):
|
||||
return
|
||||
|
||||
root.setLevel(logging.DEBUG)
|
||||
fmt = logging.Formatter(_LOG_FORMAT, datefmt=_LOG_DATEFMT)
|
||||
|
||||
stream = logging.StreamHandler()
|
||||
stream.setLevel(getattr(logging, _LEVEL if _LEVEL in {'DEBUG', 'INFO', 'WARNING', 'ERROR'} else 'INFO'))
|
||||
stream.setFormatter(fmt)
|
||||
root.addHandler(stream)
|
||||
|
||||
if _FILE_ENABLED:
|
||||
try:
|
||||
_FILE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
file_handler = logging.handlers.RotatingFileHandler(
|
||||
_FILE_DIR / 'vector.log',
|
||||
maxBytes=2 * 1024 * 1024,
|
||||
backupCount=5,
|
||||
encoding='utf-8',
|
||||
)
|
||||
file_handler.setLevel(logging.INFO)
|
||||
file_handler.setFormatter(fmt)
|
||||
root.addHandler(file_handler)
|
||||
except OSError:
|
||||
root.warning('Файл-лог недоступен (%s) — только stdout', _FILE_DIR)
|
||||
|
||||
# uvicorn-логи ошибок приложения (traceback-и) идут тем же форматом
|
||||
uvicorn_error = logging.getLogger('uvicorn.error')
|
||||
uvicorn_error.handlers.clear()
|
||||
uvicorn_error.propagate = True
|
||||
|
||||
root._vector_configured = True # type: ignore[attr-defined]
|
||||
|
||||
|
||||
def get_logger(name: str) -> logging.Logger:
|
||||
"""Модульный логгер: get_logger('analyze') → 'vector.analyze'."""
|
||||
short = name.removeprefix('vector.')
|
||||
return logging.getLogger(f'vector.{short}')
|
||||
Reference in New Issue
Block a user