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__)