Coverage for lisacattools/custom_logging.py: 74%
46 statements
« prev ^ index » next coverage.py v7.0.5, created at 2023-02-06 17:36 +0000
« prev ^ index » next coverage.py v7.0.5, created at 2023-02-06 17:36 +0000
1# -*- coding: utf-8 -*-
2# Copyright (C) 2020-2021 - Centre National d'Etudes Spatiales
3# jean-christophe.malapert@cnes.fr
4#
5# This file is part of smt_crawler_lib.
6#
7# smt_crawler_lib is a free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 3.0 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20# MA 02110-1301 USA
21"""Module for customizing ths logs."""
22import logging
23from typing import Optional
26class UtilsLogs:
27 """Utility class for logs."""
29 @staticmethod
30 def addLoggingLevel(
31 levelName: str, levelNum: int, methodName: Optional[str] = None
32 ) -> None:
33 """Add a new logging level to the `logging` module.
35 Parameters
36 ----------
37 levelName: str
38 level name of the logging
39 levelNum: int
40 level number related to the level name
41 methodName: Optional[str]
42 method for both `logging` itself and the class returned by
43 `logging.Logger`
45 Returns
46 -------
47 None
49 Raises
50 ------
51 AttributeError
52 If this levelName or methodName is already defined in the
53 logger.
55 """
56 if not methodName:
57 methodName = levelName.lower()
59 def logForLevel(self, message, *args, **kwargs):
60 if self.isEnabledFor(levelNum):
61 self._log(levelNum, message, args, **kwargs)
63 def logToRoot(message, *args, **kwargs):
64 logging.log(levelNum, message, *args, **kwargs)
66 logging.addLevelName(levelNum, levelName)
67 setattr(logging, levelName, levelNum)
68 setattr(logging.getLoggerClass(), methodName, logForLevel)
69 setattr(logging, methodName, logToRoot)
72class LogRecord(logging.LogRecord):
73 """Specific class to handle output in logs."""
75 def getMessage(self) -> str:
76 """Return the message.
78 Format the message according to the type of the message.
80 Returns
81 -------
82 str
83 the message
84 """
85 msg = str(self.msg)
86 if isinstance(self.args, dict):
87 return msg.format(self.args)
88 return msg % self.args if self.args else msg
91class CustomColorFormatter(logging.Formatter):
92 """Color formatter."""
94 UtilsLogs.addLoggingLevel("TRACE", 15)
95 # Reset
96 color_Off = "\033[0m" # Text Reset
98 log_colors = {
99 logging.TRACE: "\033[0;36m", # cyan
100 logging.DEBUG: "\033[1;34m", # blue
101 logging.INFO: "\033[0;32m", # green
102 logging.WARNING: "\033[1;33m", # yellow
103 logging.ERROR: "\033[1;31m", # red
104 logging.CRITICAL: "\033[1;41m", # red reverted
105 }
107 def format(self, record: LogRecord) -> str: # type: ignore
108 """Format the log.
110 Parameters
111 ----------
112 record: LogRecord
113 the log record
115 Returns
116 -------
117 str
118 the formatted log record
119 """
120 record.levelname = "{}{}{}".format(
121 CustomColorFormatter.log_colors[record.levelno],
122 record.levelname,
123 CustomColorFormatter.color_Off,
124 )
125 record.msg = "{}{}{}".format(
126 CustomColorFormatter.log_colors[record.levelno],
127 record.msg,
128 CustomColorFormatter.color_Off,
129 )
131 # Select the formatter according to the log if several handlers are
132 # attached to the logger
133 my_formatter = logging.Formatter
134 my_handler = None
135 handlers = logging.getLogger(__name__).handlers
136 for handler in handlers:
137 handler_level = handler.level
138 if (
139 handler_level
140 == logging.getLogger(__name__).getEffectiveLevel()
141 ):
142 my_formatter._fmt = handler.formatter._fmt
143 my_handler = handler
144 break
145 if my_handler is not None:
146 [
147 logging.getLogger(__name__).removeHandler(handler)
148 for handler in handlers
149 if handler != my_handler
150 ]
151 return my_formatter.format(self, record)
154class ShellColorFormatter(CustomColorFormatter):
155 """Shell Color formatter."""
157 def format(self, record: LogRecord) -> str:
158 """Format the log.
160 Parameters
161 ----------
162 record: LogRecord
163 the log record
165 Returns
166 -------
167 str
168 the formatted log record
169 """
170 record.msg = "{}{}{}".format(
171 CustomColorFormatter.log_colors[logging.INFO],
172 record.msg,
173 CustomColorFormatter.color_Off,
174 )
175 return record.msg