fix: defer daily report push и увеличить pool БД (0.4.12)
FCM/каналы для report.daily.* после commit ingest (BackgroundTasks); SAC_DB_POOL_SIZE=15, SAC_DB_MAX_OVERFLOW=25 для штурма 09:00. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException, Query
|
||||
from fastapi import APIRouter, BackgroundTasks, Body, Depends, HTTPException, Query
|
||||
from fastapi.responses import JSONResponse
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import func, select
|
||||
@@ -51,6 +51,7 @@ from app.services.notify_dispatch import (
|
||||
notify_lifecycle,
|
||||
notify_problem,
|
||||
notify_rdg_connection,
|
||||
schedule_notify_daily_report,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/events", tags=["events"])
|
||||
@@ -79,6 +80,7 @@ def _ingest_response(event: Event, *, created: bool) -> IngestResponse:
|
||||
|
||||
@router.post("", response_model=IngestResponse)
|
||||
def post_event(
|
||||
background_tasks: BackgroundTasks,
|
||||
payload: dict[str, Any] = Body(...),
|
||||
db: Session = Depends(get_db),
|
||||
_api_key: str = Depends(get_api_key_auth),
|
||||
@@ -96,11 +98,12 @@ def post_event(
|
||||
event, created = ingest_event(db, payload)
|
||||
problem = None
|
||||
problem_created = False
|
||||
deferred_daily_report_id: int | None = None
|
||||
if created:
|
||||
problem, problem_created = maybe_create_problem(db, event)
|
||||
maybe_auto_disconnect_stuck_rdp_session(db, event)
|
||||
if event.type in DAILY_REPORT_EVENT_TYPES:
|
||||
notify_daily_report(event, db=db)
|
||||
deferred_daily_report_id = event.id
|
||||
elif event.type == LIFECYCLE_EVENT_TYPE:
|
||||
notify_lifecycle(event, db=db)
|
||||
elif event.type in AUTH_LOGIN_SUCCESS_TYPES:
|
||||
@@ -116,6 +119,9 @@ def post_event(
|
||||
logger.info("ingest duplicate event_id=%s", event.event_id)
|
||||
db.commit()
|
||||
|
||||
if deferred_daily_report_id is not None:
|
||||
background_tasks.add_task(schedule_notify_daily_report, deferred_daily_report_id)
|
||||
|
||||
body = _ingest_response(event, created=created)
|
||||
if problem is not None:
|
||||
body.problem_id = problem.id
|
||||
|
||||
@@ -34,6 +34,8 @@ class Settings(BaseSettings):
|
||||
model_config = _settings_config()
|
||||
|
||||
database_url: str = "postgresql+psycopg2://sac:sac@localhost:5432/sac"
|
||||
sac_db_pool_size: int = 15
|
||||
sac_db_max_overflow: int = 25
|
||||
sac_public_url: str = "http://localhost:8000"
|
||||
jwt_secret: str = "change-me-in-production"
|
||||
jwt_algorithm: str = "HS256"
|
||||
|
||||
@@ -6,7 +6,11 @@ from sqlalchemy.orm import DeclarativeBase, Session, sessionmaker
|
||||
from app.config import get_settings
|
||||
|
||||
settings = get_settings()
|
||||
engine = create_engine(settings.database_url, pool_pre_ping=True)
|
||||
_engine_kwargs: dict = {"pool_pre_ping": True}
|
||||
if settings.database_url.startswith("postgresql"):
|
||||
_engine_kwargs["pool_size"] = max(1, int(settings.sac_db_pool_size))
|
||||
_engine_kwargs["max_overflow"] = max(0, int(settings.sac_db_max_overflow))
|
||||
engine = create_engine(settings.database_url, **_engine_kwargs)
|
||||
SessionLocal = sessionmaker(bind=engine, autocommit=False, autoflush=False)
|
||||
|
||||
|
||||
|
||||
@@ -142,3 +142,20 @@ def notify_rdg_connection(event: Event, *, db: Session | None = None) -> None:
|
||||
if not should_notify_event(event, db):
|
||||
return
|
||||
_dispatch_lifecycle_channels(event, db=db, policy=policy)
|
||||
|
||||
|
||||
def schedule_notify_daily_report(event_db_id: int) -> None:
|
||||
"""Отложенное оповещение по суточному отчёту (после commit ingest, вне горячего POST)."""
|
||||
from app.database import SessionLocal
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
event = db.get(Event, event_db_id)
|
||||
if event is None:
|
||||
logger.warning("deferred daily report notify: event id=%s not found", event_db_id)
|
||||
return
|
||||
notify_daily_report(event, db=db)
|
||||
except Exception:
|
||||
logger.exception("deferred daily report notify failed event_db_id=%s", event_db_id)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"""Единый источник версии SAC (API, health, логи, OpenAPI)."""
|
||||
|
||||
APP_NAME = "Security Alert Center"
|
||||
APP_VERSION = "0.4.11"
|
||||
APP_VERSION = "0.4.12"
|
||||
APP_VERSION_LABEL = f"{APP_NAME} v.{APP_VERSION}"
|
||||
|
||||
Reference in New Issue
Block a user