from __future__ import annotations import logging from datetime import datetime from typing import Callable, Optional from zoneinfo import ZoneInfo from motor.motor_asyncio import AsyncIOMotorCollection logger = logging.getLogger(__name__) class ApiLogger: """Persists API invocation metadata for observability/auditing.""" def __init__(self, collection_getter: Callable[[], AsyncIOMotorCollection]) -> None: self._collection_getter = collection_getter def _collection(self) -> AsyncIOMotorCollection: return self._collection_getter() @staticmethod def _current_ist_timestamp() -> str: now = datetime.now(ZoneInfo("Asia/Kolkata")) return now.strftime("%d-%m-%Y %H:%M:%S:%Z") async def log_categorization( self, *, name: str, status: str, response_time: float, user_id: Optional[str], error_message: Optional[str] = None, ) -> None: doc = { "name": name, "status": status, "date": self._current_ist_timestamp(), "response_time": round(response_time, 3), } if user_id: doc["user_id"] = user_id if error_message: doc["error_message"] = error_message try: await self._collection().insert_one(doc) except Exception: logger.exception("Failed to write categorize API log")