# cmcp/utils/logging.py
# container-mcp © 2025 by Martin Bukowski is licensed under Apache 2.0
"""Logging utilities for Container-MCP."""
import logging
import sys
import os
from typing import Optional
def setup_logging(
log_level: str = "INFO",
log_file: Optional[str] = None,
log_format: Optional[str] = None,
) -> None:
"""Set up logging for the application.
Args:
log_level: The log level to use.
log_file: Optional path to a log file.
log_format: Optional log format string.
"""
# Define log levels
log_levels = {
"DEBUG": logging.DEBUG,
"INFO": logging.INFO,
"WARNING": logging.WARNING,
"ERROR": logging.ERROR,
"CRITICAL": logging.CRITICAL,
}
# Set default format if not provided
if log_format is None:
log_format = "[%(asctime)s] [%(levelname)s] [%(name)s] %(message)s"
# Configure root logger
root_logger = logging.getLogger()
root_logger.setLevel(log_levels.get(log_level.upper(), logging.INFO))
# Remove existing handlers
for handler in root_logger.handlers:
root_logger.removeHandler(handler)
# Create formatter
formatter = logging.Formatter(log_format)
# Create console handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
root_logger.addHandler(console_handler)
# Add file handler if specified
if log_file:
# Ensure the directory exists
log_dir = os.path.dirname(log_file)
if log_dir and not os.path.exists(log_dir):
os.makedirs(log_dir, exist_ok=True)
file_handler = logging.FileHandler(log_file)
file_handler.setFormatter(formatter)
root_logger.addHandler(file_handler)
# Configure library loggers to be less verbose
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.getLogger("asyncio").setLevel(logging.WARNING)
# Log startup message
logger = logging.getLogger(__name__)
logger.debug(f"Logging initialized at level {log_level}")
def get_logger(name: str) -> logging.Logger:
"""Get a logger with the specified name.
Args:
name: The name of the logger.
Returns:
A configured logger instance.
"""
return logging.getLogger(name)