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:
@@ -1,5 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
@@ -8,6 +10,7 @@ from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from backend.database import db
|
||||
from backend.logging_setup import get_logger
|
||||
from backend.routers.auth import require_roles
|
||||
from services.rules_analysis import rules_analyze
|
||||
from services.search_engine import (
|
||||
@@ -15,6 +18,8 @@ from services.search_engine import (
|
||||
build_search_model,
|
||||
)
|
||||
|
||||
log = get_logger('analyze')
|
||||
|
||||
router = APIRouter(prefix='/api/v1/analyze', tags=['analyze'])
|
||||
|
||||
|
||||
@@ -44,6 +49,8 @@ class AnalysisRequest(BaseModel):
|
||||
async def analyze_case(payload: AnalysisRequest) -> dict[str, Any]:
|
||||
# B14: роутер — тонкая обёртка. Вся расчётная логика — в
|
||||
# services/search_engine.py::build_search_model (без DB/auth/HTTP).
|
||||
import time as _time
|
||||
_t0 = _time.monotonic()
|
||||
case_data: dict[str, Any] = {
|
||||
'age': payload.age,
|
||||
'gender': payload.gender,
|
||||
@@ -109,6 +116,13 @@ async def analyze_case(payload: AnalysisRequest) -> dict[str, Any]:
|
||||
result['case_id'] = str(payload.case_id) if payload.case_id else None
|
||||
result['analyzed_at'] = datetime.now(timezone.utc).isoformat()
|
||||
|
||||
log.info(
|
||||
'анализ case=%s радиус=%.1fкм срочность=%s зон=%d время=%.0fмс',
|
||||
payload.case_id or '—', result.get('search_radius_km') or 0,
|
||||
result.get('urgency'), len(result.get('primary_zones') or []),
|
||||
(_time.monotonic() - _t0) * 1000,
|
||||
)
|
||||
|
||||
if payload.case_id is not None:
|
||||
db.update_case(str(payload.case_id), analysis_log=result, status='analyzed')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user