"""Structured logging helpers for the GCMD classifier MVP.""" from __future__ import annotations import logging from typing import Any _SECRET_MARKERS = ("api_key", "apikey", "authorization", "token", "secret", "password", "header") def get_logger(name: str = "gcmd_classifier") -> logging.Logger: """Return a package logger without forcing global logging configuration.""" return logging.getLogger(name) def sanitize_log_details(details: dict[str, Any]) -> dict[str, Any]: """Remove values whose keys look like secrets or sensitive headers.""" sanitized: dict[str, Any] = {} for key, value in details.items(): lowered = key.lower() if any(marker in lowered for marker in _SECRET_MARKERS): sanitized[key] = "[REDACTED]" elif isinstance(value, dict): sanitized[key] = sanitize_log_details(value) else: sanitized[key] = value return sanitized def log_event(logger: logging.Logger, event: str, **details: Any) -> None: """Emit a structured event through standard logging without secrets.""" safe_details = sanitize_log_details(details) logger.info("gcmd_classifier_event", extra={"event": event, "details": safe_details})