Files
cvfs/alveslib/logger.py
Daniel Alves Rösel 90ad5e0260 Initial commit
2026-04-02 18:47:14 +02:00

84 lines
2.5 KiB
Python

import json
import logging
import os
from datetime import datetime
from pathlib import Path
try:
from dotenv import load_dotenv
load_dotenv()
except ImportError:
pass
try:
from logging_loki import LokiHandler
LOKI_AVAILABLE = True
except ImportError:
LOKI_AVAILABLE = False
def get_logger(service_name: str, level: str = "INFO") -> logging.Logger:
"""
Get a configured logger for UltiPlate services.
Args:
service_name: Name of the service/module
level: Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
Returns:
Configured logger instance
"""
logger = logging.getLogger(service_name)
logger.setLevel(getattr(logging, level.upper()))
if not logger.handlers:
# Console handler with JSON formatting
handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter(service_name))
logger.addHandler(handler)
# File handler - writes to logs directory
logs_dir = Path(os.getenv("LOGDIR", "./logs"))
logs_dir.mkdir(parents=True, exist_ok=True)
file_handler = logging.FileHandler(logs_dir / f"{service_name}.log")
file_handler.setFormatter(JsonFormatter(service_name))
logger.addHandler(file_handler)
# Loki handler - sends logs directly to Loki
if LOKI_AVAILABLE:
loki_port = os.getenv("LOKI_PORT", "3100")
loki_url = f"http://localhost:{loki_port}/loki/api/v1/push"
try:
loki_handler = LokiHandler(
url=loki_url,
tags={"service": service_name},
version="1"
)
logger.addHandler(loki_handler)
except Exception as e:
# If Loki is not available, just continue with file/console logging
pass
return logger
class JsonFormatter(logging.Formatter):
def __init__(self, service_name: str):
super().__init__()
self.service_name = service_name
def format(self, record):
log_entry = {
"timestamp": datetime.utcnow().isoformat() + "Z",
"service": self.service_name,
"level": record.levelname,
"message": record.getMessage(),
"module": record.module,
"function": record.funcName,
"line": record.lineno
}
if record.exc_info:
log_entry["exception"] = self.formatException(record.exc_info)
return json.dumps(log_entry)