main
py 52 lines 1.59 KB
Raw
1 from __future__ import annotations
2
3 import json
4 import logging
5 from datetime import datetime, timezone
6 from time import monotonic
7 from typing import Any
8
9 from opentelemetry import trace
10
11
12 logger = logging.getLogger("yahoo_finance_mcp.audit")
13
14
15 class YahooMcpAudit:
16 def __init__(self, *, service: str, environment: str) -> None:
17 self.service = service
18 self.environment = environment
19
20 def emit(
21 self,
22 event: str,
23 *,
24 request_id: str,
25 global_instrument_id: str,
26 symbol: str,
27 tool: str,
28 started: float,
29 error_code: str | None = None,
30 ) -> None:
31 span_context = trace.get_current_span().get_span_context()
32 payload: dict[str, Any] = {
33 "timestamp": datetime.now(timezone.utc).isoformat(),
34 "service": self.service,
35 "environment": self.environment,
36 "level": "INFO" if event in {"YAHOO_MCP_REQUEST", "YAHOO_MCP_SUCCESS"} else "WARNING",
37 "event": event,
38 "requestId": request_id,
39 "globalInstrumentId": global_instrument_id,
40 "yahooSymbol": symbol,
41 "tool": tool,
42 "durationMs": max(0, round((monotonic() - started) * 1000, 2)),
43 }
44 if span_context.is_valid:
45 payload["traceId"] = format(span_context.trace_id, "032x")
46 if error_code:
47 payload["errorCode"] = error_code
48 message = json.dumps(payload, separators=(",", ":"), sort_keys=True)
49 if payload["level"] == "WARNING":
50 logger.warning(message)
51 else:
52 logger.info(message)