mcp-calculator/src/mcp_calculator/logging_setup.py
2026-09-15 20:38:16 +02:00

36 lines
1.4 KiB
Python

"""Logging to stderr (stdout is the protocol channel in stdio mode)."""
from __future__ import annotations
import json
import logging
import sys
from datetime import UTC, datetime
class JsonFormatter(logging.Formatter):
"""One JSON object per line, for log aggregation."""
def format(self, record: logging.LogRecord) -> str:
entry = {
"time": datetime.fromtimestamp(record.created, tz=UTC).isoformat(timespec="milliseconds"),
"level": record.levelname,
"logger": record.name,
"message": record.getMessage(),
}
if record.exc_info:
entry["exception"] = self.formatException(record.exc_info)
return json.dumps(entry, ensure_ascii=False)
def setup_logging(level: str = "INFO", fmt: str = "text") -> None:
handler = logging.StreamHandler(sys.stderr)
if fmt == "json":
handler.setFormatter(JsonFormatter())
else:
handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)-7s %(name)s: %(message)s"))
logging.basicConfig(level=level.upper(), handlers=[handler], force=True)
# The SDK logs every request at INFO; keep it quieter unless debugging.
if level.upper() != "DEBUG":
for noisy in ("mcp.server.lowlevel.server", "mcp.server.streamable_http", "mcp.server.streamable_http_manager"):
logging.getLogger(noisy).setLevel(logging.WARNING)