Mercurial > libervia-backend
comparison sat/core/log_config.py @ 4037:524856bd7b19
massive refactoring to switch from camelCase to snake_case:
historically, Libervia (SàT before) was using camelCase as allowed by PEP8 when using a
pre-PEP8 code, to use the same coding style as in Twisted.
However, snake_case is more readable and it's better to follow PEP8 best practices, so it
has been decided to move on full snake_case. Because Libervia has a huge codebase, this
ended with a ugly mix of camelCase and snake_case.
To fix that, this patch does a big refactoring by renaming every function and method
(including bridge) that are not coming from Twisted or Wokkel, to use fully snake_case.
This is a massive change, and may result in some bugs.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 08 Apr 2023 13:54:42 +0200 |
parents | 760f563b1243 |
children |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
45 **kwargs, | 45 **kwargs, |
46 ) | 46 ) |
47 | 47 |
48 | 48 |
49 class ConfigureBasic(log.ConfigureBase): | 49 class ConfigureBasic(log.ConfigureBase): |
50 def configureColors(self, colors, force_colors, levels_taints_dict): | 50 def configure_colors(self, colors, force_colors, levels_taints_dict): |
51 super(ConfigureBasic, self).configureColors( | 51 super(ConfigureBasic, self).configure_colors( |
52 colors, force_colors, levels_taints_dict | 52 colors, force_colors, levels_taints_dict |
53 ) | 53 ) |
54 if colors: | 54 if colors: |
55 import sys | 55 import sys |
56 | 56 |
59 except AttributeError: | 59 except AttributeError: |
60 isatty = False | 60 isatty = False |
61 # FIXME: isatty should be tested on each handler, not globaly | 61 # FIXME: isatty should be tested on each handler, not globaly |
62 if (force_colors or isatty): | 62 if (force_colors or isatty): |
63 # we need colors | 63 # we need colors |
64 log.Logger.post_treat = lambda logger, level, message: self.ansiColors( | 64 log.Logger.post_treat = lambda logger, level, message: self.ansi_colors( |
65 level, message | 65 level, message |
66 ) | 66 ) |
67 elif force_colors: | 67 elif force_colors: |
68 raise ValueError("force_colors can't be used if colors is False") | 68 raise ValueError("force_colors can't be used if colors is False") |
69 | 69 |
70 @staticmethod | 70 @staticmethod |
71 def getProfile(): | 71 def get_profile(): |
72 """Try to find profile value using introspection""" | 72 """Try to find profile value using introspection""" |
73 import inspect | 73 import inspect |
74 | 74 |
75 stack = inspect.stack() | 75 stack = inspect.stack() |
76 current_path = stack[0][1] | 76 current_path = stack[0][1] |
105 | 105 |
106 | 106 |
107 class ConfigureTwisted(ConfigureBasic): | 107 class ConfigureTwisted(ConfigureBasic): |
108 LOGGER_CLASS = TwistedLogger | 108 LOGGER_CLASS = TwistedLogger |
109 | 109 |
110 def preTreatment(self): | 110 def pre_treatment(self): |
111 from twisted import logger | 111 from twisted import logger |
112 global logger | 112 global logger |
113 self.level_map = { | 113 self.level_map = { |
114 C.LOG_LVL_DEBUG: logger.LogLevel.debug, | 114 C.LOG_LVL_DEBUG: logger.LogLevel.debug, |
115 C.LOG_LVL_INFO: logger.LogLevel.info, | 115 C.LOG_LVL_INFO: logger.LogLevel.info, |
117 C.LOG_LVL_ERROR: logger.LogLevel.error, | 117 C.LOG_LVL_ERROR: logger.LogLevel.error, |
118 C.LOG_LVL_CRITICAL: logger.LogLevel.critical, | 118 C.LOG_LVL_CRITICAL: logger.LogLevel.critical, |
119 } | 119 } |
120 self.LOGGER_CLASS.level_map = self.level_map | 120 self.LOGGER_CLASS.level_map = self.level_map |
121 | 121 |
122 def configureLevel(self, level): | 122 def configure_level(self, level): |
123 self.level = self.level_map[level] | 123 self.level = self.level_map[level] |
124 | 124 |
125 def configureOutput(self, output): | 125 def configure_output(self, output): |
126 import sys | 126 import sys |
127 from twisted.python import logfile | 127 from twisted.python import logfile |
128 self.log_publisher = logger.LogPublisher() | 128 self.log_publisher = logger.LogPublisher() |
129 | 129 |
130 if output is None: | 130 if output is None: |
131 output = C.LOG_OPT_OUTPUT_SEP + C.LOG_OPT_OUTPUT_DEFAULT | 131 output = C.LOG_OPT_OUTPUT_SEP + C.LOG_OPT_OUTPUT_DEFAULT |
132 self.manageOutputs(output) | 132 self.manage_outputs(output) |
133 | 133 |
134 if C.LOG_OPT_OUTPUT_DEFAULT in log.handlers: | 134 if C.LOG_OPT_OUTPUT_DEFAULT in log.handlers: |
135 if self.backend_data is None: | 135 if self.backend_data is None: |
136 raise ValueError( | 136 raise ValueError( |
137 "You must pass options as backend_data with Twisted backend" | 137 "You must pass options as backend_data with Twisted backend" |
138 ) | 138 ) |
139 options = self.backend_data | 139 options = self.backend_data |
140 log_file = logfile.LogFile.fromFullPath(options['logfile']) | 140 log_file = logfile.LogFile.fromFullPath(options['logfile']) |
141 self.log_publisher.addObserver( | 141 self.log_publisher.addObserver( |
142 logger.FileLogObserver(log_file, self.textFormatter)) | 142 logger.FileLogObserver(log_file, self.text_formatter)) |
143 # we also want output to stdout if we are in debug or nodaemon mode | 143 # we also want output to stdout if we are in debug or nodaemon mode |
144 if options.get("nodaemon", False) or options.get("debug", False): | 144 if options.get("nodaemon", False) or options.get("debug", False): |
145 self.log_publisher.addObserver( | 145 self.log_publisher.addObserver( |
146 logger.FileLogObserver(sys.stdout, self.textFormatter)) | 146 logger.FileLogObserver(sys.stdout, self.text_formatter)) |
147 | 147 |
148 if C.LOG_OPT_OUTPUT_FILE in log.handlers: | 148 if C.LOG_OPT_OUTPUT_FILE in log.handlers: |
149 | 149 |
150 for path in log.handlers[C.LOG_OPT_OUTPUT_FILE]: | 150 for path in log.handlers[C.LOG_OPT_OUTPUT_FILE]: |
151 log_file = ( | 151 log_file = ( |
152 sys.stdout if path == "-" else logfile.LogFile.fromFullPath(path) | 152 sys.stdout if path == "-" else logfile.LogFile.fromFullPath(path) |
153 ) | 153 ) |
154 self.log_publisher.addObserver( | 154 self.log_publisher.addObserver( |
155 logger.FileLogObserver(log_file, self.textFormatter)) | 155 logger.FileLogObserver(log_file, self.text_formatter)) |
156 | 156 |
157 if C.LOG_OPT_OUTPUT_MEMORY in log.handlers: | 157 if C.LOG_OPT_OUTPUT_MEMORY in log.handlers: |
158 raise NotImplementedError( | 158 raise NotImplementedError( |
159 "Memory observer is not implemented in Twisted backend" | 159 "Memory observer is not implemented in Twisted backend" |
160 ) | 160 ) |
161 | 161 |
162 def configureColors(self, colors, force_colors, levels_taints_dict): | 162 def configure_colors(self, colors, force_colors, levels_taints_dict): |
163 super(ConfigureTwisted, self).configureColors( | 163 super(ConfigureTwisted, self).configure_colors( |
164 colors, force_colors, levels_taints_dict | 164 colors, force_colors, levels_taints_dict |
165 ) | 165 ) |
166 self.LOGGER_CLASS.colors = colors | 166 self.LOGGER_CLASS.colors = colors |
167 self.LOGGER_CLASS.force_colors = force_colors | 167 self.LOGGER_CLASS.force_colors = force_colors |
168 if force_colors and not colors: | 168 if force_colors and not colors: |
169 raise ValueError("colors must be True if force_colors is True") | 169 raise ValueError("colors must be True if force_colors is True") |
170 | 170 |
171 def postTreatment(self): | 171 def post_treatment(self): |
172 """Install twistedObserver which manage non SàT logs""" | 172 """Install twistedObserver which manage non SàT logs""" |
173 # from twisted import logger | 173 # from twisted import logger |
174 import sys | 174 import sys |
175 filtering_obs = logger.FilteringLogObserver( | 175 filtering_obs = logger.FilteringLogObserver( |
176 observer=self.log_publisher, | 176 observer=self.log_publisher, |
178 logger.LogLevelFilterPredicate(self.level), | 178 logger.LogLevelFilterPredicate(self.level), |
179 ] | 179 ] |
180 ) | 180 ) |
181 logger.globalLogBeginner.beginLoggingTo([filtering_obs]) | 181 logger.globalLogBeginner.beginLoggingTo([filtering_obs]) |
182 | 182 |
183 def textFormatter(self, event): | 183 def text_formatter(self, event): |
184 if event.get('sat_logged', False): | 184 if event.get('sat_logged', False): |
185 timestamp = ''.join([logger.formatTime(event.get("log_time", None)), " "]) | 185 timestamp = ''.join([logger.formatTime(event.get("log_time", None)), " "]) |
186 return f"{timestamp}{event.get('log_format', '')}\n" | 186 return f"{timestamp}{event.get('log_format', '')}\n" |
187 else: | 187 else: |
188 eventText = logger.eventAsText( | 188 eventText = logger.eventAsText( |
217 levels_taints_dict, | 217 levels_taints_dict, |
218 force_colors, | 218 force_colors, |
219 backend_data, | 219 backend_data, |
220 ) | 220 ) |
221 | 221 |
222 def preTreatment(self): | 222 def pre_treatment(self): |
223 """We use logging methods directly, instead of using Logger""" | 223 """We use logging methods directly, instead of using Logger""" |
224 import logging | 224 import logging |
225 | 225 |
226 log.getLogger = logging.getLogger | 226 log.getLogger = logging.getLogger |
227 log.debug = logging.debug | 227 log.debug = logging.debug |
228 log.info = logging.info | 228 log.info = logging.info |
229 log.warning = logging.warning | 229 log.warning = logging.warning |
230 log.error = logging.error | 230 log.error = logging.error |
231 log.critical = logging.critical | 231 log.critical = logging.critical |
232 | 232 |
233 def configureLevel(self, level): | 233 def configure_level(self, level): |
234 if level is None: | 234 if level is None: |
235 level = C.LOG_LVL_DEBUG | 235 level = C.LOG_LVL_DEBUG |
236 self.level = level | 236 self.level = level |
237 | 237 |
238 def configureFormat(self, fmt): | 238 def configure_format(self, fmt): |
239 super(ConfigureStandard, self).configureFormat(fmt) | 239 super(ConfigureStandard, self).configure_format(fmt) |
240 import logging | 240 import logging |
241 | 241 |
242 class SatFormatter(logging.Formatter): | 242 class SatFormatter(logging.Formatter): |
243 """Formatter which manage SàT specificities""" | 243 """Formatter which manage SàT specificities""" |
244 _format = fmt | 244 _format = fmt |
248 super(SatFormatter, self).__init__(self._format) | 248 super(SatFormatter, self).__init__(self._format) |
249 self.can_colors = can_colors | 249 self.can_colors = can_colors |
250 | 250 |
251 def format(self, record): | 251 def format(self, record): |
252 if self._with_profile: | 252 if self._with_profile: |
253 record.profile = ConfigureStandard.getProfile() | 253 record.profile = ConfigureStandard.get_profile() |
254 do_color = self.with_colors and (self.can_colors or self.force_colors) | 254 do_color = self.with_colors and (self.can_colors or self.force_colors) |
255 if ConfigureStandard._color_location: | 255 if ConfigureStandard._color_location: |
256 # we copy raw formatting strings for color_* | 256 # we copy raw formatting strings for color_* |
257 # as formatting is handled in ansiColors in this case | 257 # as formatting is handled in ansi_colors in this case |
258 if do_color: | 258 if do_color: |
259 record.color_start = log.COLOR_START | 259 record.color_start = log.COLOR_START |
260 record.color_end = log.COLOR_END | 260 record.color_end = log.COLOR_END |
261 else: | 261 else: |
262 record.color_start = record.color_end = "" | 262 record.color_start = record.color_end = "" |
263 s = super(SatFormatter, self).format(record) | 263 s = super(SatFormatter, self).format(record) |
264 if do_color: | 264 if do_color: |
265 s = ConfigureStandard.ansiColors(record.levelname, s) | 265 s = ConfigureStandard.ansi_colors(record.levelname, s) |
266 return s | 266 return s |
267 | 267 |
268 self.formatterClass = SatFormatter | 268 self.formatterClass = SatFormatter |
269 | 269 |
270 def configureOutput(self, output): | 270 def configure_output(self, output): |
271 self.manageOutputs(output) | 271 self.manage_outputs(output) |
272 | 272 |
273 def configureLogger(self, logger): | 273 def configure_logger(self, logger): |
274 self.name_filter = log.FilterName(logger) if logger else None | 274 self.name_filter = log.FilterName(logger) if logger else None |
275 | 275 |
276 def configureColors(self, colors, force_colors, levels_taints_dict): | 276 def configure_colors(self, colors, force_colors, levels_taints_dict): |
277 super(ConfigureStandard, self).configureColors( | 277 super(ConfigureStandard, self).configure_colors( |
278 colors, force_colors, levels_taints_dict | 278 colors, force_colors, levels_taints_dict |
279 ) | 279 ) |
280 self.formatterClass.with_colors = colors | 280 self.formatterClass.with_colors = colors |
281 self.formatterClass.force_colors = force_colors | 281 self.formatterClass.force_colors = force_colors |
282 if not colors and force_colors: | 282 if not colors and force_colors: |
283 raise ValueError("force_colors can't be used if colors is False") | 283 raise ValueError("force_colors can't be used if colors is False") |
284 | 284 |
285 def _addHandler(self, root_logger, hdlr, can_colors=False): | 285 def _add_handler(self, root_logger, hdlr, can_colors=False): |
286 hdlr.setFormatter(self.formatterClass(can_colors)) | 286 hdlr.setFormatter(self.formatterClass(can_colors)) |
287 root_logger.addHandler(hdlr) | 287 root_logger.addHandler(hdlr) |
288 root_logger.setLevel(self.level) | 288 root_logger.setLevel(self.level) |
289 if self.name_filter is not None: | 289 if self.name_filter is not None: |
290 hdlr.addFilter(self.name_filter) | 290 hdlr.addFilter(self.name_filter) |
291 | 291 |
292 def postTreatment(self): | 292 def post_treatment(self): |
293 import logging | 293 import logging |
294 | 294 |
295 root_logger = logging.getLogger() | 295 root_logger = logging.getLogger() |
296 if len(root_logger.handlers) == 0: | 296 if len(root_logger.handlers) == 0: |
297 for handler, options in list(log.handlers.items()): | 297 for handler, options in list(log.handlers.items()): |
299 hdlr = logging.StreamHandler() | 299 hdlr = logging.StreamHandler() |
300 try: | 300 try: |
301 can_colors = hdlr.stream.isatty() | 301 can_colors = hdlr.stream.isatty() |
302 except AttributeError: | 302 except AttributeError: |
303 can_colors = False | 303 can_colors = False |
304 self._addHandler(root_logger, hdlr, can_colors=can_colors) | 304 self._add_handler(root_logger, hdlr, can_colors=can_colors) |
305 elif handler == C.LOG_OPT_OUTPUT_MEMORY: | 305 elif handler == C.LOG_OPT_OUTPUT_MEMORY: |
306 from logging.handlers import BufferingHandler | 306 from logging.handlers import BufferingHandler |
307 | 307 |
308 class SatMemoryHandler(BufferingHandler): | 308 class SatMemoryHandler(BufferingHandler): |
309 def emit(self, record): | 309 def emit(self, record): |
313 log.handlers[ | 313 log.handlers[ |
314 handler | 314 handler |
315 ] = ( | 315 ] = ( |
316 hdlr | 316 hdlr |
317 ) # we keep a reference to the handler to read the buffer later | 317 ) # we keep a reference to the handler to read the buffer later |
318 self._addHandler(root_logger, hdlr, can_colors=False) | 318 self._add_handler(root_logger, hdlr, can_colors=False) |
319 elif handler == C.LOG_OPT_OUTPUT_FILE: | 319 elif handler == C.LOG_OPT_OUTPUT_FILE: |
320 import os.path | 320 import os.path |
321 | 321 |
322 for path in options: | 322 for path in options: |
323 hdlr = logging.FileHandler(os.path.expanduser(path)) | 323 hdlr = logging.FileHandler(os.path.expanduser(path)) |
324 self._addHandler(root_logger, hdlr, can_colors=False) | 324 self._add_handler(root_logger, hdlr, can_colors=False) |
325 else: | 325 else: |
326 raise ValueError("Unknown handler type") | 326 raise ValueError("Unknown handler type") |
327 else: | 327 else: |
328 root_logger.warning("Handlers already set on root logger") | 328 root_logger.warning("Handlers already set on root logger") |
329 | 329 |
330 @staticmethod | 330 @staticmethod |
331 def memoryGet(size=None): | 331 def memory_get(size=None): |
332 """Return buffered logs | 332 """Return buffered logs |
333 | 333 |
334 @param size: number of logs to return | 334 @param size: number of logs to return |
335 """ | 335 """ |
336 mem_handler = log.handlers[C.LOG_OPT_OUTPUT_MEMORY] | 336 mem_handler = log.handlers[C.LOG_OPT_OUTPUT_MEMORY] |
353 C.LOG_BACKEND_CUSTOM: use a given Logger subclass | 353 C.LOG_BACKEND_CUSTOM: use a given Logger subclass |
354 """ | 354 """ |
355 return log.configure(backend, **options) | 355 return log.configure(backend, **options) |
356 | 356 |
357 | 357 |
358 def _parseOptions(options): | 358 def _parse_options(options): |
359 """Parse string options as given in conf or environment variable, and return expected python value | 359 """Parse string options as given in conf or environment variable, and return expected python value |
360 | 360 |
361 @param options (dict): options with (key: name, value: string value) | 361 @param options (dict): options with (key: name, value: string value) |
362 """ | 362 """ |
363 COLORS = C.LOG_OPT_COLORS[0] | 363 COLORS = C.LOG_OPT_COLORS[0] |
376 if level not in C.LOG_LEVELS: | 376 if level not in C.LOG_LEVELS: |
377 level = C.LOG_LVL_INFO | 377 level = C.LOG_LVL_INFO |
378 options[LEVEL] = level | 378 options[LEVEL] = level |
379 | 379 |
380 | 380 |
381 def satConfigure(backend=C.LOG_BACKEND_STANDARD, const=None, backend_data=None): | 381 def sat_configure(backend=C.LOG_BACKEND_STANDARD, const=None, backend_data=None): |
382 """Configure logging system for SàT, can be used by frontends | 382 """Configure logging system for SàT, can be used by frontends |
383 | 383 |
384 logs conf is read in SàT conf, then in environment variables. It must be done before Memory init | 384 logs conf is read in SàT conf, then in environment variables. It must be done before Memory init |
385 @param backend: backend to use, it can be: | 385 @param backend: backend to use, it can be: |
386 - C.LOG_BACKEND_BASIC: print based backend | 386 - C.LOG_BACKEND_BASIC: print based backend |
394 log.C = const | 394 log.C = const |
395 from sat.tools import config | 395 from sat.tools import config |
396 import os | 396 import os |
397 | 397 |
398 log_conf = {} | 398 log_conf = {} |
399 sat_conf = config.parseMainConf() | 399 sat_conf = config.parse_main_conf() |
400 for opt_name, opt_default in C.LOG_OPTIONS(): | 400 for opt_name, opt_default in C.LOG_OPTIONS(): |
401 try: | 401 try: |
402 log_conf[opt_name] = os.environ[ | 402 log_conf[opt_name] = os.environ[ |
403 "".join((C.ENV_PREFIX, C.LOG_OPT_PREFIX.upper(), opt_name.upper())) | 403 "".join((C.ENV_PREFIX, C.LOG_OPT_PREFIX.upper(), opt_name.upper())) |
404 ] | 404 ] |
405 except KeyError: | 405 except KeyError: |
406 log_conf[opt_name] = config.getConfig( | 406 log_conf[opt_name] = config.config_get( |
407 sat_conf, C.LOG_OPT_SECTION, C.LOG_OPT_PREFIX + opt_name, opt_default | 407 sat_conf, C.LOG_OPT_SECTION, C.LOG_OPT_PREFIX + opt_name, opt_default |
408 ) | 408 ) |
409 | 409 |
410 _parseOptions(log_conf) | 410 _parse_options(log_conf) |
411 configure(backend, backend_data=backend_data, **log_conf) | 411 configure(backend, backend_data=backend_data, **log_conf) |