(continued from previous page) handlers : console : class : logging.StreamHandler level : DEBUG formatter : simple stream : ext://sys.stdout loggers : simpleExample : level : DEBUG handlers : [console] propagate : no root : level : DEBUG handlers : [console] For more information about logging using a dictionary, see logging-config-api. If no logging configuration is provided, it is possible to have a situation where a logging event needs to be output, but no handlers can be found to output the event. The behaviour of the logging package in these circumstances is dependent on the Python version. For versions of Python prior to 3.2, the behaviour is as follows: In Python 3.2 and later, the behaviour is as follows: To obtain the pre-3.2 behaviour,$_{logging.lastResort}$ can be set to$_{None}$ . When developing a library which uses logging, you should take care to document how the library uses logging - for example, the names of loggers used. Some consideration also needs to be given to its logging configuration. If the using application does not use logging, and library code makes logging calls, then (as described in the previous section) events of severity WARNING and greater will be printed to sys.stderr . This is regarded as the best default behaviour. If for some reason you don’t want these messages printed in the absence of any logging configuration, you can attach a do-nothing handler to the top-level logger for your library. This avoids the message being printed, since a handler will always be found for the library’s events: it just doesn’t produce any output. If the library user configures logging for application use, presumably that configuration will add some handlers, and if levels are suitably configured then logging calls made in library code will send output to those handlers, as normal. A do-nothing handler is included in the logging package: $_{NullHandler}$(since Python 3.1). An instance of this handler could be added to the top-level logger of the logging namespace used by the library ( if you want to prevent your library’s logged events being output to$_{sys.stderr}$in the absence of logging configuration). If all logging by a library foo is done using loggers with names matching ‘foo.x’, ‘foo.x.y’, etc. then the code: 2.7 Configuring Logging for a Library 2.6 What happens if no configuration is provided • The event is output using a ‘handler of last resort’, stored in$_{logging.lastResort}$ . This internal handler is not associated with any logger, and acts like a$_{StreamHandler}$which writes the event description message to the current value of $_{sys.stderr}$(therefore respecting any redirections which may be in effect). No formatting is done on the message - just the bare event description message is printed. The handler’s level is set to$_{WARNING}$ , so all events at this and greater severities will be output. • If logging.raiseExceptions is True (development mode), a message ‘No handlers could be found for logger X.Y.Z’ is printed once. • If logging.raiseExceptions is$_{False}$ (production mode), the event is silently dropped. 12