File size: 6,437 Bytes
3241ff4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import logging


def get_handlers(

    filename="app.log", mode="w", file_level=logging.DEBUG, stderr_level=logging.DEBUG

):
    """

    The function `get_handlers` returns a stream handler and a file handler with specified logging

    levels and formatters.



    Args:

      filename: The `filename` parameter is the name of the log file where the log messages will be

    written. In this case, the default filename is "app.log". Defaults to app.log

      mode: The `mode` parameter in the `get_handlers` function specifies the mode in which the file

    should be opened. In this case, the default mode is set to "w", which stands for write mode. This

    means that if the file already exists, it will be truncated (i.e., its. Defaults to w

      file_level: The `file_level` parameter in the `get_handlers` function is used to specify the

    logging level for the file handler. In this case, it is set to `logging.DEBUG`, which means that the

    file handler will log all messages at the DEBUG level and above.

      stderr_level: The `stderr_level` parameter in the `get_handlers` function is used to specify the

    logging level for the StreamHandler that outputs log messages to the standard error stream (stderr).

    This level determines which log messages will be processed and output by the StreamHandler.



    Returns:

      The `get_handlers` function returns two logging handlers: `stderr_handler` which is a

    StreamHandler for logging to stderr, and `file_handler` which is a FileHandler for logging to a file

    specified by the `filename` parameter.

    """
    # Stream handler
    stderr_handler = logging.StreamHandler()
    stderr_handler.setLevel(stderr_level)
    stderr_handler.setFormatter(CustomFormatter())

    # File handler
    file_handler = logging.FileHandler(filename, mode=mode)
    file_handler.setLevel(file_level)
    file_handler.setFormatter(CustomFormatter(True))

    # TODO: Add RotatingFileHandler

    return stderr_handler, file_handler


class CustomFormatter(logging.Formatter):
    """

    A custom log formatter that adds color to log messages based on the log level.



    Args:

        file (bool): Indicates whether the log is being written to a file. Default is False.



    Attributes:

        FORMATS (dict): A dictionary mapping log levels to colorized log message formats.



    Methods:

        format(record): Formats the log record with the appropriate colorized log message format.



    """

    def __init__(self, file=False):
        """

        This function initializes logging formats with different colors and styles based on the log

        level.



        Args:

          file: The `file` parameter in the `__init__` method is a boolean flag that determines whether

        the logging output should be colored or not. If `file` is `True`, the colors will not be applied

        to the log messages. Defaults to False

        """
        super().__init__()
        yellow = "\x1b[36;10m" if not file else ""
        blue = "\x1b[35;10m" if not file else ""
        green = "\x1b[32;10m" if not file else ""
        red = "\x1b[31;10m" if not file else ""
        bold_red = "\x1b[31;1m" if not file else ""
        reset = "\x1b[0m" if not file else ""
        log = "%(asctime)s (%(filename)s:%(lineno)d) - %(levelname)s: "
        msg = reset + "%(message)s"

        self.FORMATS = {
            logging.DEBUG: blue + log + msg,
            logging.INFO: green + log + msg,
            logging.WARNING: yellow + log + msg,
            logging.ERROR: red + log + msg,
            logging.CRITICAL: bold_red + log + msg,
        }

    def format(self, record):
        """

        Formats the log record with the appropriate colorized log message format.



        Args:

            record (LogRecord): The log record to be formatted.



        Returns:

            str: The formatted log message.



        """
        log_fmt = self.FORMATS.get(record.levelno)
        formatter = logging.Formatter(log_fmt)
        return formatter.format(record)


def init_logging_config(

    basic_log_level=logging.INFO,

    filename="app.log",

    mode="w",

    file_level=logging.DEBUG,

    stderr_level=logging.DEBUG,

):
    """

    The function `init_logging_config` initializes logging configuration in Python by setting basic log

    level, configuring handlers, and adding them to the logger.



    Args:

      basic_log_level: The `basic_log_level` parameter is used to set the logging level for the root

    logger. In this function, it is set to `logging.INFO` by default, which means that log messages with

    severity level INFO or higher will be processed.

      filename: The `filename` parameter is a string that specifies the name of the log file where the

    logs will be written. In the `init_logging_config` function you provided, the default value for

    `filename` is "app.log". This means that if no filename is provided when calling the function, logs.

    Defaults to app.log

      mode: The `mode` parameter in the `init_logging_config` function specifies the mode in which the

    log file will be opened. In this case, the default value is "w" which stands for write mode. This

    means that the log file will be opened for writing, and if the file already exists. Defaults to w

      file_level: The `file_level` parameter in the `init_logging_config` function is used to specify

    the logging level for the file handler. This determines the severity level of log messages that will

    be written to the log file specified by the `filename` parameter. In this case, the default value

    for `file

      stderr_level: The `stderr_level` parameter in the `init_logging_config` function is used to

    specify the logging level for the stderr (standard error) handler. This handler is responsible for

    directing log messages to the standard error stream. The logging level determines which severity of

    log messages will be output to the stderr.

    """

    logger = logging.getLogger()
    logger.setLevel(basic_log_level)

    # Get the handlers
    stderr_handler, file_handler = get_handlers(
        file_level=file_level, stderr_level=stderr_level, filename=filename, mode=mode
    )

    # Add the handlers
    logger.addHandler(stderr_handler)
    logger.addHandler(file_handler)