Mercurial > libervia-backend
comparison sat/core/log.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 | 1b7c6ee080b9 |
children |
comparison
equal
deleted
inserted
replaced
4036:c4464d7ae97b | 4037:524856bd7b19 |
---|---|
119 record = {'name': self._name, | 119 record = {'name': self._name, |
120 'message': message, | 120 'message': message, |
121 'levelname': level, | 121 'levelname': level, |
122 } | 122 } |
123 try: | 123 try: |
124 if not self.filter_name.dictFilter(record): | 124 if not self.filter_name.dict_filter(record): |
125 raise Filtered | 125 raise Filtered |
126 except (AttributeError, TypeError): # XXX: TypeError is here because of a pyjamas bug which need to be fixed (TypeError is raised instead of AttributeError) | 126 except (AttributeError, TypeError): # XXX: TypeError is here because of a pyjamas bug which need to be fixed (TypeError is raised instead of AttributeError) |
127 if self.filter_name is not None: | 127 if self.filter_name is not None: |
128 raise ValueError("Bad filter: filters must have a .filter method") | 128 raise ValueError("Bad filter: filters must have a .filter method") |
129 try: | 129 try: |
131 except TypeError: | 131 except TypeError: |
132 return message | 132 return message |
133 except KeyError as e: | 133 except KeyError as e: |
134 if e.args[0] == 'profile': | 134 if e.args[0] == 'profile': |
135 # XXX: %(profile)s use some magic with introspection, for debugging purpose only *DO NOT* use in production | 135 # XXX: %(profile)s use some magic with introspection, for debugging purpose only *DO NOT* use in production |
136 record['profile'] = configure_cls[backend].getProfile() | 136 record['profile'] = configure_cls[backend].get_profile() |
137 return self.fmt % record | 137 return self.fmt % record |
138 else: | 138 else: |
139 raise e | 139 raise e |
140 | 140 |
141 def debug(self, msg: object, **kwargs) -> None: | 141 def debug(self, msg: object, **kwargs) -> None: |
172 def filter(self, record): | 172 def filter(self, record): |
173 if self.name_re.search(record.name) is not None: | 173 if self.name_re.search(record.name) is not None: |
174 return 1 | 174 return 1 |
175 return 0 | 175 return 0 |
176 | 176 |
177 def dictFilter(self, dict_record): | 177 def dict_filter(self, dict_record): |
178 """Filter using a dictionary record | 178 """Filter using a dictionary record |
179 | 179 |
180 @param dict_record: dictionary with at list a key "name" with logger name | 180 @param dict_record: dictionary with at list a key "name" with logger name |
181 @return: True if message should be logged | 181 @return: True if message should be logged |
182 """ | 182 """ |
206 Use search to match expression, so ^ or $ can be necessary. | 206 Use search to match expression, so ^ or $ can be necessary. |
207 @param colors: if True use ANSI colors to show log levels | 207 @param colors: if True use ANSI colors to show log levels |
208 @param force_colors: if True ANSI colors are used even if stdout is not a tty | 208 @param force_colors: if True ANSI colors are used even if stdout is not a tty |
209 """ | 209 """ |
210 self.backend_data = backend_data | 210 self.backend_data = backend_data |
211 self.preTreatment() | 211 self.pre_treatment() |
212 self.configureLevel(level) | 212 self.configure_level(level) |
213 self.configureFormat(fmt) | 213 self.configure_format(fmt) |
214 self.configureOutput(output) | 214 self.configure_output(output) |
215 self.configureLogger(logger) | 215 self.configure_logger(logger) |
216 self.configureColors(colors, force_colors, levels_taints_dict) | 216 self.configure_colors(colors, force_colors, levels_taints_dict) |
217 self.postTreatment() | 217 self.post_treatment() |
218 self.updateCurrentLogger() | 218 self.update_current_logger() |
219 | 219 |
220 def updateCurrentLogger(self): | 220 def update_current_logger(self): |
221 """update existing logger to the class needed for this backend""" | 221 """update existing logger to the class needed for this backend""" |
222 if self.LOGGER_CLASS is None: | 222 if self.LOGGER_CLASS is None: |
223 return | 223 return |
224 for name, logger in list(_loggers.items()): | 224 for name, logger in list(_loggers.items()): |
225 _loggers[name] = self.LOGGER_CLASS(logger) | 225 _loggers[name] = self.LOGGER_CLASS(logger) |
226 | 226 |
227 def preTreatment(self): | 227 def pre_treatment(self): |
228 pass | 228 pass |
229 | 229 |
230 def configureLevel(self, level): | 230 def configure_level(self, level): |
231 if level is not None: | 231 if level is not None: |
232 # we deactivate methods below level | 232 # we deactivate methods below level |
233 level_idx = C.LOG_LEVELS.index(level) | 233 level_idx = C.LOG_LEVELS.index(level) |
234 def dev_null(self, msg): | 234 def dev_null(self, msg): |
235 pass | 235 pass |
236 for _level in C.LOG_LEVELS[:level_idx]: | 236 for _level in C.LOG_LEVELS[:level_idx]: |
237 setattr(Logger, _level.lower(), dev_null) | 237 setattr(Logger, _level.lower(), dev_null) |
238 | 238 |
239 def configureFormat(self, fmt): | 239 def configure_format(self, fmt): |
240 if fmt is not None: | 240 if fmt is not None: |
241 if fmt != '%(message)s': # %(message)s is the same as None | 241 if fmt != '%(message)s': # %(message)s is the same as None |
242 Logger.fmt = fmt | 242 Logger.fmt = fmt |
243 if COLOR_START in fmt: | 243 if COLOR_START in fmt: |
244 ConfigureBase._color_location = True | 244 ConfigureBase._color_location = True |
245 if fmt.find(COLOR_END,fmt.rfind(COLOR_START))<0: | 245 if fmt.find(COLOR_END,fmt.rfind(COLOR_START))<0: |
246 # color_start not followed by an end, we add it | 246 # color_start not followed by an end, we add it |
247 Logger.fmt += COLOR_END | 247 Logger.fmt += COLOR_END |
248 | 248 |
249 def configureOutput(self, output): | 249 def configure_output(self, output): |
250 if output is not None: | 250 if output is not None: |
251 if output != C.LOG_OPT_OUTPUT_SEP + C.LOG_OPT_OUTPUT_DEFAULT: | 251 if output != C.LOG_OPT_OUTPUT_SEP + C.LOG_OPT_OUTPUT_DEFAULT: |
252 # TODO: manage other outputs | 252 # TODO: manage other outputs |
253 raise NotImplementedError("Basic backend only manage default output yet") | 253 raise NotImplementedError("Basic backend only manage default output yet") |
254 | 254 |
255 def configureLogger(self, logger): | 255 def configure_logger(self, logger): |
256 if logger: | 256 if logger: |
257 Logger.filter_name = FilterName(logger) | 257 Logger.filter_name = FilterName(logger) |
258 | 258 |
259 def configureColors(self, colors, force_colors, levels_taints_dict): | 259 def configure_colors(self, colors, force_colors, levels_taints_dict): |
260 if colors: | 260 if colors: |
261 # if color are used, we need to handle levels_taints_dict | 261 # if color are used, we need to handle levels_taints_dict |
262 for level in list(levels_taints_dict.keys()): | 262 for level in list(levels_taints_dict.keys()): |
263 # we wants levels in uppercase to correspond to contstants | 263 # we wants levels in uppercase to correspond to contstants |
264 levels_taints_dict[level.upper()] = levels_taints_dict[level] | 264 levels_taints_dict[level.upper()] = levels_taints_dict[level] |
278 # we use raw string if element is unknown | 278 # we use raw string if element is unknown |
279 ansi = elt | 279 ansi = elt |
280 ansi_list.append(ansi) | 280 ansi_list.append(ansi) |
281 taints[level] = ''.join(ansi_list) | 281 taints[level] = ''.join(ansi_list) |
282 | 282 |
283 def postTreatment(self): | 283 def post_treatment(self): |
284 pass | 284 pass |
285 | 285 |
286 def manageOutputs(self, outputs_raw): | 286 def manage_outputs(self, outputs_raw): |
287 """ Parse output option in a backend agnostic way, and fill handlers consequently | 287 """ Parse output option in a backend agnostic way, and fill handlers consequently |
288 | 288 |
289 @param outputs_raw: output option as enterred in environment variable or in configuration | 289 @param outputs_raw: output option as enterred in environment variable or in configuration |
290 """ | 290 """ |
291 if not outputs_raw: | 291 if not outputs_raw: |
328 | 328 |
329 if options: # we should not have unparsed options | 329 if options: # we should not have unparsed options |
330 raise ValueError("options [{options}] are not supported for {handler} output".format(options=options, handler=output)) | 330 raise ValueError("options [{options}] are not supported for {handler} output".format(options=options, handler=output)) |
331 | 331 |
332 @staticmethod | 332 @staticmethod |
333 def memoryGet(size=None): | 333 def memory_get(size=None): |
334 """Return buffered logs | 334 """Return buffered logs |
335 | 335 |
336 @param size: number of logs to return | 336 @param size: number of logs to return |
337 """ | 337 """ |
338 raise NotImplementedError | 338 raise NotImplementedError |
339 | 339 |
340 @classmethod | 340 @classmethod |
341 def ansiColors(cls, level, message): | 341 def ansi_colors(cls, level, message): |
342 """Colorise message depending on level for terminals | 342 """Colorise message depending on level for terminals |
343 | 343 |
344 @param level: one of C.LOG_LEVELS | 344 @param level: one of C.LOG_LEVELS |
345 @param message: formatted message to log | 345 @param message: formatted message to log |
346 @return: message with ANSI escape codes for coloration | 346 @return: message with ANSI escape codes for coloration |
356 'color_end': A.RESET} | 356 'color_end': A.RESET} |
357 else: | 357 else: |
358 return '%s%s%s' % (start, message, A.RESET) | 358 return '%s%s%s' % (start, message, A.RESET) |
359 | 359 |
360 @staticmethod | 360 @staticmethod |
361 def getProfile(): | 361 def get_profile(): |
362 """Try to find profile value using introspection""" | 362 """Try to find profile value using introspection""" |
363 raise NotImplementedError | 363 raise NotImplementedError |
364 | 364 |
365 | 365 |
366 class ConfigureCustom(ConfigureBase): | 366 class ConfigureCustom(ConfigureBase): |
394 logger_class = options.pop('logger_class') | 394 logger_class = options.pop('logger_class') |
395 configure_class(logger_class, **options) | 395 configure_class(logger_class, **options) |
396 else: | 396 else: |
397 configure_class(**options) | 397 configure_class(**options) |
398 | 398 |
399 def memoryGet(size=None): | 399 def memory_get(size=None): |
400 if not C.LOG_OPT_OUTPUT_MEMORY in handlers: | 400 if not C.LOG_OPT_OUTPUT_MEMORY in handlers: |
401 raise ValueError('memory output is not used') | 401 raise ValueError('memory output is not used') |
402 return configure_cls[backend].memoryGet(size) | 402 return configure_cls[backend].memory_get(size) |
403 | 403 |
404 def getLogger(name=C.LOG_BASE_LOGGER) -> Logger: | 404 def getLogger(name=C.LOG_BASE_LOGGER) -> Logger: |
405 try: | 405 try: |
406 logger_class = configure_cls[backend].LOGGER_CLASS | 406 logger_class = configure_cls[backend].LOGGER_CLASS |
407 except KeyError: | 407 except KeyError: |