Coverage for csvforwkt/custom_logging.py: 92%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# -*- coding: utf-8 -*-
2# csvForWKT - csvForWKT is a python script that creates a WKT-crs for some bodies from the solar system. The content that is filled in the WKT-crs comes from the report of IAU Working Group on Cartographic.
3# Copyright (C) 2022 - CNES (Jean-Christophe Malapert for Pôle Surfaces Planétaires)
4#
5# This file is part of csvForWKT.
6#
7# csvForWKT is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Lesser General Public License v3 as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# csvForWKT 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
15# GNU Lesser General Public License v3 for more details.
16#
17# You should have received a copy of the GNU Lesser General Public License v3
18# along with csvForWKT. If not, see <https://www.gnu.org/licenses/>.
19"""Module for customizing ths logs."""
20import logging
21from typing import Optional
24class UtilsLogs: # pylint: disable=R0903
25 """Utility class for logs."""
27 @staticmethod
28 def add_logging_level(
29 level_name: str, level_num: int, method_name: Optional[str] = None
30 ) -> None:
31 """Add a new logging level to the `logging` module.
33 Parameters
34 ----------
35 level_name: str
36 level name of the logging
37 level_num: int
38 level number related to the level name
39 method_name: Optional[str]
40 method for both `logging` itself and the class returned by
41 `logging.Logger`
43 Returns
44 -------
45 None
47 Raises
48 ------
49 AttributeError
50 If this levelName or methodName is already defined in the
51 logger.
53 """
54 if not method_name:
55 method_name = level_name.lower()
57 def log_for_level(self, message, *args, **kwargs):
58 if self.isEnabledFor(level_num):
59 self._log( # pylint: disable=W0212
60 level_num, message, args, **kwargs
61 )
63 def log_to_root(message, *args, **kwargs):
64 logging.log(level_num, message, *args, **kwargs)
66 logging.addLevelName(level_num, level_name)
67 setattr(logging, level_name, level_num)
68 setattr(logging.getLoggerClass(), method_name, log_for_level)
69 setattr(logging, method_name, log_to_root)
72class LogRecord(logging.LogRecord): # pylint: disable=R0903
73 """Specific class to handle output in logs."""
75 def getMessage(self) -> str:
76 """Returns the message.
78 Format the message according to the type of the message.
80 Returns:
81 str: Returns the message
82 """
83 msg = self.msg
84 if self.args:
85 if isinstance(self.args, dict):
86 msg = msg.format(**self.args)
87 else:
88 msg = msg.format(*self.args)
89 return msg
92class CustomColorFormatter(logging.Formatter):
93 """Color formatter."""
95 UtilsLogs.add_logging_level("TRACE", 15)
96 # Reset
97 color_Off = "\033[0m" # Text Reset
99 log_colors = {
100 logging.TRACE: "\033[0;36m", # type: ignore # pylint: disable=no-member # cyan
101 logging.DEBUG: "\033[1;34m", # blue
102 logging.INFO: "\033[0;32m", # green
103 logging.WARNING: "\033[1;33m", # yellow
104 logging.ERROR: "\033[1;31m", # red
105 logging.CRITICAL: "\033[1;41m", # red reverted
106 }
108 def format(self, record) -> str:
109 """Format the log.
111 Args:
112 record: the log record
114 Returns:
115 str: the formatted log record
116 """
117 record.levelname = "{}{}{}".format(
118 CustomColorFormatter.log_colors[record.levelno],
119 record.levelname,
120 CustomColorFormatter.color_Off,
121 )
122 record.msg = "{}{}{}".format(
123 CustomColorFormatter.log_colors[record.levelno],
124 record.msg,
125 CustomColorFormatter.color_Off,
126 )
128 # Select the formatter according to the log if several handlers are
129 # attached to the logger
130 my_formatter = logging.Formatter
131 my_handler = None
132 handlers = logging.getLogger(__name__).handlers
133 for handler in handlers:
134 handler_level = handler.level
135 if (
136 handler_level
137 == logging.getLogger(__name__).getEffectiveLevel()
138 ):
139 if handler.formatter:
140 my_formatter._fmt = ( # pylint: disable=W0212
141 handler.formatter._fmt # pylint: disable=W0212
142 )
143 my_handler = handler
144 break
145 if my_handler is not None:
146 for handler in handlers:
147 if handler != my_handler:
148 logging.getLogger(__name__).removeHandler(handler)
149 return my_formatter.format(self, record) # type: ignore
152class ShellColorFormatter(CustomColorFormatter):
153 """Shell Color formatter."""
155 def format(self, record) -> str:
156 """Format the log.
158 Args:
159 record: the log record
161 Returns:
162 str: the formatted log record
163 """
164 record.msg = "{}{}{}".format(
165 CustomColorFormatter.log_colors[logging.INFO],
166 record.msg,
167 CustomColorFormatter.color_Off,
168 )
169 return record.msg