(continued from previous page) (continues on next page) 26 logger=logging.getLogger('setup') logger.critical( 'Should not appear, because of disabled logger ... ') for i in range(100 ): lvl=random.choice(levels) logger=logging.getLogger(random .choice(loggers)) logger.log(lvl, 'Message no. %d ', i) time.sleep( 0.01 ) def main(): q =Queue() # The main process gets a simple configuration which prints to the console. config_initial={ 'version':1, 'handlers': { 'console': { 'class':'logging.StreamHandler ', 'level ':'INFO ' } }, 'root': { 'handlers': ['console'], 'level ':'DEBUG' } } # The worker process configuration is just a QueueHandler attached to the # root logger, which allows all messages to be sent to the queue. # We disable existing loggers to disable the "setup" logger used in the # parent process. This is needed on POSIX because the logger will # be there in the child following a fork(). config_worker={ 'version':1, 'disable_existing_loggers ': True , 'handlers': { 'queue': { 'class':'logging.handlers.QueueHandler ', 'queue': q } }, 'root': { 'handlers': ['queue'], 'level ':'DEBUG' } } # The listener process configuration shows that the full flexibility of # logging configuration is available to dispatch events to handlers however # you want. # We disable existing loggers to disable the "setup" logger used in the # parent process. This is needed on POSIX because the logger will # be there in the child following a fork(). config_listener={ 'version':1, 'disable_existing_loggers ': True , 'formatters': { 'detailed': { 'class':'logging.Formatter ', 'format':' %(asctime)s %(name)-15s %(levelname)-8s %(processName)- ↪ → 10s%(message)s ' }, 'simple': { 'class':'logging.Formatter ', 'format':' %(name)-15s %(levelname)-8s %(processName)-10s ↪ → %(message)s '