"""JSON-formatted structured logging for machine readability.""" from __future__ import annotations import json import logging import sys from datetime import UTC, datetime from typing import Any class JSONFormatter(logging.Formatter): """Emit log records as single-line JSON objects.""" def format(self, record: logging.LogRecord) -> str: log_entry: dict[str, Any] = { "timestamp": datetime.now(UTC).isoformat(), "level": record.levelname, "logger": record.name, "message": record.getMessage(), } if record.exc_info and record.exc_info[1]: log_entry["exception"] = self.formatException(record.exc_info) # Merge any extra fields attached to the record for key in ("stock_code", "action", "confidence", "pnl_pct", "order_amount"): value = getattr(record, key, None) if value is not None: log_entry[key] = value return json.dumps(log_entry, ensure_ascii=False) def setup_logging(level: int = logging.INFO) -> None: """Configure the root logger with JSON output to stdout.""" handler = logging.StreamHandler(sys.stdout) handler.setFormatter(JSONFormatter()) root = logging.getLogger() root.setLevel(level) # Avoid duplicate handlers on repeated calls root.handlers.clear() root.addHandler(handler)