36 lines
1.4 KiB
Python
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)
|