File size: 6,292 Bytes
46917c3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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)