17 Comprehensively adds a new logging level to the `logging` module and the
18 currently configured logging class.
20 `levelName` becomes an attribute of the `logging` module with the value
21 `levelNum`. `methodName` becomes a convenience method for both `logging`
22 itself and the class returned by `logging.getLoggerClass()` (usually just
23 `logging.Logger`). If `methodName` is not specified, `levelName.lower()` is
26 To avoid accidental clobberings of existing attributes, this method will
27 raise an `AttributeError` if the level name is already an attribute of the
28 `logging` module or if the method name is already present
32 >>> addLoggingLevel('TRACE', logging.DEBUG - 5)
33 >>> logging.getLogger(__name__).setLevel("TRACE")
34 >>> logging.getLogger(__name__).trace('that worked')
35 >>> logging.trace('so did this')
41 methodName = levelName.lower()
43 if hasattr(logging, levelName):
45 '{} already defined in logging module'.format(levelName),
47 if hasattr(logging, methodName):
49 '{} already defined in logging module'.format(methodName),
51 if hasattr(logging.getLoggerClass(), methodName):
53 '{} already defined in logger class'.format(methodName),
59 def logForLevel(self, message, *args, **kwargs):
60 if self.isEnabledFor(levelNum):
61 self._log(levelNum, message, args, **kwargs)
63 def logToRoot(message, *args, **kwargs):
64 logging.log(levelNum, message, *args, **kwargs)
66 logging.addLevelName(levelNum, levelName)
67 setattr(logging, levelName, levelNum)
68 setattr(logging.getLoggerClass(), methodName, logForLevel)
69 setattr(logging, methodName, logToRoot)