Issue 958180: logging functionality non-intuitive, levels confusing (original) (raw)

If one tries to define additional logging levels without overriding the logger class, one runs into trouble with the log level naming conventions. In particular, I observe the following strange behavior:

import logging logging.basicConfig() logging.root.level 30 logging.root.log( logging.INFO, 'test1' ) logging.root.log( 20, 'test1' ) logging.root.log( 'info', 'test1' ) Level info:root:test1 logging.root.log( 'INFO', 'test1' ) 20:root:test1 logging.root.log( logging.WARNING, 'warning' ) WARNING:root:warning logging.root.log( 30, 'warning' ) WARNING:root:warning logging.root.log( 'warning', 'warning' ) Level warning:root:warning logging.root.log( 'WARNING', 'warning' ) 30:root:warning

Note that if a string parameter is passed as the lvl parameter of the log() method, the message is logged regardless of the current logging level, and the output is furthermore inconsistent.

Additionally, when the user attempts to add a logging level, the user cannot reference that log level by name using any exposed (documented) interfaces.

For example:

import logging logging.basicConfig() logging.root.level = logging.DEBUG # 10 logging.addLevelName( 15, 'STATUS' ) logging.root.log( 15, 'a status message' ) STATUS:root:a status message logging.root.log( logging._levelNames['STATUS'], 'a status message' ) STATUS:root:a status message

The only interface, as far as I can tell, to access the log level is to explicitly query the internal data structures.

Changes I propose: (1) The log() methodshould either throw a TypeError when a string is passed for the log level or (better) it should accept string values and translate them transparently to the integer log levels that it currently expects.

(2) The logging module should include functionality to allow the user to query a logging level from a name.

def getLevelNumber( levelName ): return _levelNames[ levelName ] # error checking would be appropriate