@ -16,7 +16,7 @@ import json
import time
import time
import traceback
import traceback
import uuid
import uuid
from datetime import datetime , time zone
from datetime import datetime , time delta, time zone
from typing import Callable , Optional
from typing import Callable , Optional
from fastapi import Request , Response
from fastapi import Request , Response
@ -38,6 +38,8 @@ logger = logging.getLogger(__name__)
_REQUEST_LOG_QUEUE : asyncio . Queue = asyncio . Queue ( maxsize = 10_000 )
_REQUEST_LOG_QUEUE : asyncio . Queue = asyncio . Queue ( maxsize = 10_000 )
_FLUSH_INTERVAL_SECONDS : float = 2.0 # flush at most every 2 s
_FLUSH_INTERVAL_SECONDS : float = 2.0 # flush at most every 2 s
_FLUSH_BATCH_SIZE : int = 500 # or when 500 entries are queued
_FLUSH_BATCH_SIZE : int = 500 # or when 500 entries are queued
_LOG_RETENTION_DAYS : int = 7 # delete request_logs older than this
_CLEANUP_INTERVAL_HOURS : int = 1 # run cleanup every N hours
async def _flush_request_logs ( entries : list ) - > None :
async def _flush_request_logs ( entries : list ) - > None :
@ -82,9 +84,31 @@ async def _request_log_flusher() -> None:
await _flush_request_logs ( entries )
await _flush_request_logs ( entries )
async def _request_log_cleanup ( ) - > None :
""" Background coroutine: delete request_logs older than _LOG_RETENTION_DAYS. """
while True :
await asyncio . sleep ( _CLEANUP_INTERVAL_HOURS * 3600 )
try :
cutoff = datetime . now ( timezone . utc ) - timedelta ( days = _LOG_RETENTION_DAYS )
from app . core . database import AsyncSessionLocal
from sqlalchemy import text
async with AsyncSessionLocal ( ) as db :
result = await db . execute (
text ( " DELETE FROM request_logs WHERE created_at < :cutoff " ) ,
{ " cutoff " : cutoff } ,
)
deleted = result . rowcount
await db . commit ( )
if deleted :
logger . info ( f " request_logs cleanup: deleted { deleted } rows older than { _LOG_RETENTION_DAYS } d " )
except Exception as e :
logger . error ( f " request_logs cleanup failed: { e } " )
def start_request_log_flusher ( ) - > None :
def start_request_log_flusher ( ) - > None :
""" Schedule the background flusher coroutine. Call once at app startup. """
""" Schedule the background flusher coroutine. Call once at app startup. """
asyncio . ensure_future ( _request_log_flusher ( ) )
asyncio . ensure_future ( _request_log_flusher ( ) )
asyncio . ensure_future ( _request_log_cleanup ( ) )
logger . info ( " Request log flusher background task started " )
logger . info ( " Request log flusher background task started " )