comparison src/core/log.py @ 1942:7f053e1f0b67

core (logs): taints: log taints can be specified using log_levels_taints_dict in sat.conf, where key is a level name, and value is a list of color or code names. For instance, the following conf would taint INFO level in bold/green and DEBUG in default color: log_levels_taints_dict = {"debug": [], "info": ["green", "bold"]} Unknown names are copied as raw strings.
author Goffi <goffi@goffi.org>
date Mon, 18 Apr 2016 18:35:17 +0200
parents 3fdacba9da68
children 7cbffd754b4a
comparison
equal deleted inserted replaced
1941:befdcfc55569 1942:7f053e1f0b67
157 157
158 class ConfigureBase(object): 158 class ConfigureBase(object):
159 LOGGER_CLASS = Logger 159 LOGGER_CLASS = Logger
160 _color_location = False # True if color location is specified in fmt (with COLOR_START) 160 _color_location = False # True if color location is specified in fmt (with COLOR_START)
161 161
162 def __init__(self, level=None, fmt=None, output=None, logger=None, colors=False, force_colors=False, backend_data=None): 162 def __init__(self, level=None, fmt=None, output=None, logger=None, colors=False, levels_taints_dict=None, force_colors=False, backend_data=None):
163 """Configure a backend 163 """Configure a backend
164 164
165 @param level: one of C.LOG_LEVELS 165 @param level: one of C.LOG_LEVELS
166 @param fmt: format string, pretty much as in std logging. Accept the following keywords (maybe more depending on backend): 166 @param fmt: format string, pretty much as in std logging. Accept the following keywords (maybe more depending on backend):
167 - "message" 167 - "message"
176 self.preTreatment() 176 self.preTreatment()
177 self.configureLevel(level) 177 self.configureLevel(level)
178 self.configureFormat(fmt) 178 self.configureFormat(fmt)
179 self.configureOutput(output) 179 self.configureOutput(output)
180 self.configureLogger(logger) 180 self.configureLogger(logger)
181 self.configureColors(colors, force_colors) 181 self.configureColors(colors, force_colors, levels_taints_dict)
182 self.postTreatment() 182 self.postTreatment()
183 self.updateCurrentLogger() 183 self.updateCurrentLogger()
184 184
185 def updateCurrentLogger(self): 185 def updateCurrentLogger(self):
186 """update existing logger to the class needed for this backend""" 186 """update existing logger to the class needed for this backend"""
219 219
220 def configureLogger(self, logger): 220 def configureLogger(self, logger):
221 if logger: 221 if logger:
222 Logger.filter_name = FilterName(logger) 222 Logger.filter_name = FilterName(logger)
223 223
224 def configureColors(self, colors, force_colors): 224 def configureColors(self, colors, force_colors, levels_taints_dict):
225 pass 225 if colors:
226 # if color are used, we need to handle levels_taints_dict
227 for level in levels_taints_dict.keys():
228 # we wants levels in uppercase to correspond to contstants
229 levels_taints_dict[level.upper()] = levels_taints_dict[level]
230 taints = self.__class__.taints = {}
231 for level in C.LOG_LEVELS:
232 # we want use values and use constant value as default
233 taint_list = levels_taints_dict.get(level, C.LOG_OPT_TAINTS_DICT[1][level])
234 ansi_list = []
235 for elt in taint_list:
236 elt = elt.upper()
237 try:
238 ansi = getattr(C, 'ANSI_FG_{}'.format(elt))
239 except AttributeError:
240 try:
241 ansi = getattr(C, 'ANSI_{}'.format(elt))
242 except AttributeError:
243 # we use raw string if element is unknown
244 ansi = elt
245 ansi_list.append(ansi)
246 taints[level] = ''.join(ansi_list)
226 247
227 def postTreatment(self): 248 def postTreatment(self):
228 pass 249 pass
229 250
230 def manageOutputs(self, outputs_raw): 251 def manageOutputs(self, outputs_raw):
287 308
288 @param level: one of C.LOG_LEVELS 309 @param level: one of C.LOG_LEVELS
289 @param message: formatted message to log 310 @param message: formatted message to log
290 @return: message with ANSI escape codes for coloration 311 @return: message with ANSI escape codes for coloration
291 """ 312 """
292 if level == C.LOG_LVL_DEBUG: 313
293 start = (C.ANSI_FG_CYAN,) 314 try:
294 elif level == C.LOG_LVL_INFO: 315 start = cls.taints[level]
295 start = () 316 except KeyError:
296 elif level == C.LOG_LVL_WARNING: 317 start = ''
297 start = (C.ANSI_FG_YELLOW,) 318
298 elif level == C.LOG_LVL_ERROR:
299 start = (C.ANSI_FG_RED,
300 C.ANSI_BLINK,
301 r'/!\ ',
302 C.ANSI_BLINK_OFF)
303 elif level == C.LOG_LVL_CRITICAL:
304 start = (C.ANSI_BOLD,
305 C.ANSI_FG_RED,
306 'Guru Meditation ',
307 C.ANSI_NORMAL_WEIGHT)
308 else:
309 start = ()
310 if cls._color_location: 319 if cls._color_location:
311 return message % {'color_start': ''.join(start), 320 return message % {'color_start': start,
312 'color_end': C.ANSI_RESET} 321 'color_end': C.ANSI_RESET}
313 else: 322 else:
314 return '%s%s%s' % (''.join(start), message, C.ANSI_RESET) 323 return '%s%s%s' % (start, message, C.ANSI_RESET)
315 324
316 @staticmethod 325 @staticmethod
317 def getProfile(): 326 def getProfile():
318 """Try to find profile value using introspection""" 327 """Try to find profile value using introspection"""
319 raise NotImplementedError 328 raise NotImplementedError