(continued from previous page) 

# simple example, the listener does not apply level or filter logic to received ␣ ↪ → records. # In practice, you would probably want to do this logic in the worker processes, ␣ ↪ → to avoid # sending events which would be filtered out between processes. # # The size of the rotated files is made small so you can see the results easily. def listener_configurer (): root =logging.getLogger() h =logging.handlers.RotatingFileHandler('mptest.log ','a',300 ,10 ) f =logging.Formatter(' %(asctime)s %(processName)-10s %(name)s %(levelname)-8s ↪ → %(message)s ') h .setFormatter(f) root.addHandler(h) # This is the listener process top-level loop: wait for logging events # (LogRecords)on the queue and handle them, quit when you get a None for a # LogRecord. def listener_process(queue, configurer): configurer() while True : try : record =queue.get() if record is None : # We send this as a sentinel to tell the listener ␣ ↪ → to quit. break logger=logging.getLogger(record.name) logger.handle(record) # No level or filter logic applied - just do it! except Exception: import sys , traceback print('Whoops! Problem: ', file=sys.stderr) traceback.print_exc(file =sys.stderr) # Arrays used for random selections in this demo LEVELS =[logging.DEBUG, logging .INFO, logging.WARNING, logging.ERROR, logging .CRITICAL] LOGGERS =['a.b.c ','d.e.f '] MESSAGES =[ 'Random message #1 ', 'Random message #2 ', 'Random message #3 ', ] # The worker configuration is done at the start of the worker process run. # Note that on Windows you can't rely on fork semantics, so each process # will run the logging configuration code when it starts. def worker_configurer(queue): h =logging.handlers.QueueHandler(queue) # Just the one handler needed root =logging.getLogger() root.addHandler(h) # send all messages, for demo; no other level or filter logic applied. root.setLevel(logging .DEBUG) # This is the worker process top-level loop, which just logs ten events with # random intervening delays before terminating. # The print messages are just so you know it's doing something! def worker_process(queue, configurer): configurer(queue) 

(continues on next page) 

