File size: 2,282 Bytes
d60934b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
import logging
import json
from datetime import datetime
import os
from pathlib import Path
import sys
import traceback
from typing import Dict, Any
class CustomFormatter(logging.Formatter):
"""Custom formatter that includes extra fields in the message"""
def format(self, record: logging.LogRecord) -> str:
# Get the original message
message = super().format(record)
# If there are extra fields, append them to the message
if hasattr(record, 'extra'):
extras = ' | '.join(f"{k}={v}" for k, v in record.extra.items())
message = f"{message} | {extras}"
return message
def setup_logging() -> None:
"""Configure logging with custom formatter"""
# Create logs directory if it doesn't exist
logs_dir = Path("logs")
logs_dir.mkdir(exist_ok=True)
# Create formatters
console_formatter = CustomFormatter(
'%(asctime)s | %(levelname)s | %(name)s | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
file_formatter = CustomFormatter(
'%(asctime)s | %(levelname)s | %(name)s | %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# Configure console handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(console_formatter)
# Configure file handler
current_time = datetime.now().strftime('%Y%m%d_%H%M%S')
file_handler = logging.FileHandler(
logs_dir / f'app_{current_time}.log',
encoding='utf-8'
)
file_handler.setFormatter(file_formatter)
# Configure root logger
root_logger = logging.getLogger()
root_logger.setLevel(logging.DEBUG)
# Remove any existing handlers
root_logger.handlers = []
# Add our handlers
root_logger.addHandler(console_handler)
root_logger.addHandler(file_handler)
def get_logger(name: str) -> logging.Logger:
"""Get a logger with the given name"""
return logging.getLogger(name)
class LoggerMixin:
"""Mixin to add logging capabilities to a class"""
@classmethod
def get_logger(cls) -> logging.Logger:
return get_logger(cls.__name__)
@property
def logger(self) -> logging.Logger:
return get_logger(self.__class__.__name__) |