105 lines
2.8 KiB
Python
105 lines
2.8 KiB
Python
"""Custom log formatters."""
|
|
|
|
import json
|
|
import logging
|
|
from datetime import datetime
|
|
from typing import Any, Dict
|
|
|
|
try:
|
|
import colorlog
|
|
except ImportError:
|
|
colorlog = None
|
|
|
|
|
|
class JSONFormatter(logging.Formatter):
|
|
"""JSON formatter for structured logging."""
|
|
|
|
def format(self, record: logging.LogRecord) -> str:
|
|
"""
|
|
Format log record as JSON.
|
|
|
|
Args:
|
|
record: Log record to format
|
|
|
|
Returns:
|
|
JSON string
|
|
"""
|
|
log_data: Dict[str, Any] = {
|
|
"timestamp": datetime.utcnow().isoformat(),
|
|
"level": record.levelname,
|
|
"logger": record.name,
|
|
"message": record.getMessage(),
|
|
"module": record.module,
|
|
"function": record.funcName,
|
|
"line": record.lineno,
|
|
}
|
|
|
|
# Add exception info if present
|
|
if record.exc_info:
|
|
log_data["exception"] = self.formatException(record.exc_info)
|
|
|
|
# Add extra fields
|
|
if hasattr(record, "extra_fields"):
|
|
log_data.update(record.extra_fields)
|
|
|
|
return json.dumps(log_data)
|
|
|
|
|
|
class DetailedFormatter(logging.Formatter):
|
|
"""Detailed text formatter with full context."""
|
|
|
|
def __init__(self, *args: Any, **kwargs: Any):
|
|
"""Initialize formatter."""
|
|
super().__init__(
|
|
fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s - [%(pathname)s:%(lineno)d]",
|
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
*args,
|
|
**kwargs,
|
|
)
|
|
|
|
|
|
class ColoredFormatter(logging.Formatter):
|
|
"""Colored console formatter."""
|
|
|
|
def __init__(self, *args: Any, **kwargs: Any):
|
|
"""Initialize formatter."""
|
|
if colorlog is None:
|
|
# Fallback to standard formatter if colorlog not available
|
|
super().__init__(
|
|
fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
*args,
|
|
**kwargs,
|
|
)
|
|
else:
|
|
# Use colorlog if available
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def format(self, record: logging.LogRecord) -> str:
|
|
"""
|
|
Format log record with colors.
|
|
|
|
Args:
|
|
record: Log record to format
|
|
|
|
Returns:
|
|
Formatted string with colors
|
|
"""
|
|
if colorlog is None:
|
|
return super().format(record)
|
|
|
|
# Create colored formatter
|
|
formatter = colorlog.ColoredFormatter(
|
|
"%(log_color)s%(asctime)s - %(name)s - %(levelname)s - %(message)s%(reset)s",
|
|
datefmt="%Y-%m-%d %H:%M:%S",
|
|
log_colors={
|
|
"DEBUG": "cyan",
|
|
"INFO": "green",
|
|
"WARNING": "yellow",
|
|
"ERROR": "red",
|
|
"CRITICAL": "red,bg_white",
|
|
},
|
|
)
|
|
return formatter.format(record)
|
|
|