File size: 2,604 Bytes
1778e91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
992479e
1778e91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import logging
import sys
import time
from functools import wraps
from typing import Callable, Any
from rich.logging import RichHandler
from rich.console import Console

console = Console()

def setup_logger(name: str, level: str = "INFO") -> logging.Logger:
    """
    Configure and return a Rich-formatted logger with enhanced debugging capabilities
    
    Args:
        name: Logger identifier, typically module name
        level: Logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
    
    Returns:
        Configured logger instance with rich formatting and error tracing
    """
    logging.basicConfig(
        level=level,
        format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
        datefmt="[%X]",
        handlers=[
            RichHandler(rich_tracebacks=True, markup=True),
            logging.StreamHandler(sys.stdout)
        ]
    )
    
    logger = logging.getLogger(name)
    logger.setLevel(level)
    return logger

def log_execution_time(logger: logging.Logger) -> Callable:
    """Decorator to log function execution time"""
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        def wrapper(*args: Any, **kwargs: Any) -> Any:
            start_time = time.time()
            logger.debug(f"Starting {func.__name__} with args: {args}, kwargs: {kwargs}")
            
            try:
                result = func(*args, **kwargs)
                execution_time = time.time() - start_time
                logger.debug(f"Completed {func.__name__} in {execution_time:.2f} seconds")
                return result
            except Exception as e:
                logger.error(f"Error in {func.__name__}: {str(e)}", exc_info=True)
                raise
        return wrapper
    return decorator

def log_async_execution_time(logger: logging.Logger) -> Callable:
    """Decorator to log async function execution time"""
    def decorator(func: Callable) -> Callable:
        @wraps(func)
        async def wrapper(*args: Any, **kwargs: Any) -> Any:
            start_time = time.time()
            logger.debug(f"Starting async {func.__name__} with args: {args}, kwargs: {kwargs}")
            
            try:
                result = await func(*args, **kwargs)
                execution_time = time.time() - start_time
                logger.debug(f"Completed async {func.__name__} in {execution_time:.2f} seconds")
                return result
            except Exception as e:
                logger.error(f"Error in async {func.__name__}: {str(e)}", exc_info=True)
                raise
        return wrapper
    return decorator