Files
VideoDetect/src/logging_config.py
T
2026-08-03 11:30:49 -04:00

90 lines
2.6 KiB
Python

"""
Logging configuration for VideoDetect.
Sets up JSON structured logging via python-json-logger with:
- Configurable log levels
- Standardized field names
- Log rotation
- All logs to stdout for Docker capture
"""
import json
import logging
import logging.handlers
import sys
from datetime import datetime, timezone
from python_json_logger import json_formatter
def setup_logging(
level: str = "INFO",
log_format: str = "json",
rotation_max_bytes: int = 104857600, # 100MB
rotation_backup_count: int = 10,
):
"""Configure structured logging for the application."""
log_level = getattr(logging, level.upper(), logging.INFO)
# Root logger
root_logger = logging.getLogger()
root_logger.setLevel(log_level)
# Remove existing handlers
root_logger.handlers.clear()
# Handler: stdout (for Docker capture)
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(log_level)
if log_format == "json":
formatter = JsonFormatter()
else:
formatter = logging.Formatter(
"%(asctime)s %(levelname)s %(name)s %(message)s",
datefmt="%Y-%m-%dT%H:%M:%S%z",
)
handler.setFormatter(formatter)
root_logger.addHandler(handler)
# Handler: file rotation (for persistence)
file_handler = logging.handlers.RotatingFileHandler(
filename="/logs/videodetect.log",
maxBytes=rotation_max_bytes,
backupCount=rotation_backup_count,
encoding="utf-8",
)
file_handler.setLevel(log_level)
file_handler.setFormatter(formatter)
root_logger.addHandler(file_handler)
logging.info("Logging configured: level=%s format=%s", level, log_format)
class JsonFormatter(logging.Formatter):
"""JSON log formatter with standardized fields."""
def format(self, record: logging.LogRecord) -> str:
log_data = {
"timestamp": datetime.fromtimestamp(record.created, tz=timezone.utc).isoformat(),
"level": record.levelname,
"logger": record.name,
"message": record.getMessage(),
"module": record.module,
"function": record.funcName,
"line": record.lineno,
}
# Add extra fields
if hasattr(record, "video_id"):
log_data["video_id"] = record.video_id
if hasattr(record, "metadata"):
log_data["metadata"] = record.metadata
# Add exception info if present
if record.exc_info and record.exc_info[0] is not None:
log_data["exception"] = self.formatException(record.exc_info)
return json.dumps(log_data, default=str)