File size: 3,064 Bytes
f79cf2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""Module doc string"""

import asyncio
import logging
import sys
import time
from functools import wraps

from colorama import Back, Fore, Style, init

from .config import LOGGER_LEVEL

# Initialize colorama
init(autoreset=True)

logger = logging.getLogger(__name__)

if not logger.hasHandlers():
    logger.propagate = False
    logger.setLevel(LOGGER_LEVEL)

    # Define color codes for different log levels
    log_colors = {
        logging.DEBUG: Fore.CYAN,
        logging.INFO: Fore.GREEN,
        logging.WARNING: Fore.YELLOW,
        logging.ERROR: Fore.RED,
        logging.CRITICAL: Fore.RED + Back.WHITE + Style.BRIGHT,
    }

    class ColoredFormatter(logging.Formatter):
        """Module doc string"""

        def format(self, record):
            """Module doc string"""

            levelno = record.levelno
            color = log_colors.get(levelno, "")

            # Format the message
            message = record.getMessage()

            # Format the rest of the log details
            details = self._fmt % {
                "asctime": self.formatTime(record, self.datefmt),
                "levelname": record.levelname,
                "module": record.module,
                "funcName": record.funcName,
                "lineno": record.lineno,
            }

            # Combine details and colored message
            return (
                f"{Fore.WHITE}{details} :: {color}{message}{Style.RESET_ALL}"
            )

    normal_handler = logging.StreamHandler(sys.stdout)
    normal_handler.setLevel(logging.DEBUG)
    normal_handler.addFilter(
        lambda logRecord: logRecord.levelno < logging.WARNING
    )

    error_handler = logging.StreamHandler(sys.stderr)
    error_handler.setLevel(logging.WARNING)

    formatter = ColoredFormatter(
        "%(asctime)s :: %(levelname)s :: %(module)s :: %(funcName)s :: %(lineno)d"
    )

    normal_handler.setFormatter(formatter)
    error_handler.setFormatter(formatter)

    logger.addHandler(normal_handler)
    logger.addHandler(error_handler)


def log_execution_time(func):
    """Module doc string"""

    @wraps(func)
    def sync_wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        execution_time = end_time - start_time
        message_string = (
            f"{func.__name__} executed in {execution_time:.4f} seconds"
        )
        logger.debug(message_string)
        return result

    @wraps(func)
    async def async_wrapper(*args, **kwargs):
        start_time = time.time()
        result = await func(*args, **kwargs)
        end_time = time.time()
        execution_time = end_time - start_time
        message_string = (
            f"{func.__name__} executed in {execution_time:.4f} seconds"
        )
        logger.debug(message_string)
        return result

    if asyncio.iscoroutinefunction(func):
        return async_wrapper
    return sync_wrapper