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: