summaryrefslogtreecommitdiffstats
path: root/Lib/logging
diff options
context:
space:
mode:
authorVinay Sajip <vinay_sajip@yahoo.co.uk>2010-09-08 10:46:15 (GMT)
committerVinay Sajip <vinay_sajip@yahoo.co.uk>2010-09-08 10:46:15 (GMT)
commit121a1c4e11fb2c6f11ec9c01aec2db91d86a0d40 (patch)
treee490d7912c3b07e32192f0d38d82276275d64cf4 /Lib/logging
parentfebeb00e4146c2b898ece019bf58cb6057d4ae73 (diff)
downloadcpython-121a1c4e11fb2c6f11ec9c01aec2db91d86a0d40.zip
cpython-121a1c4e11fb2c6f11ec9c01aec2db91d86a0d40.tar.gz
cpython-121a1c4e11fb2c6f11ec9c01aec2db91d86a0d40.tar.bz2
logging: Added QueueHandler.
Diffstat (limited to 'Lib/logging')
-rw-r--r--Lib/logging/handlers.py52
1 files changed, 52 insertions, 0 deletions
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
index 332aefc..487cdd5 100644
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -1134,3 +1134,55 @@ class MemoryHandler(BufferingHandler):
self.flush()
self.target = None
BufferingHandler.close(self)
+
+
+class QueueHandler(logging.Handler):
+ """
+ This handler sends events to a queue. Typically, it would be used together
+ with a multiprocessing Queue to centralise logging to file in one process
+ (in a multi-process application), so as to avoid file write contention
+ between processes.
+
+ This code is new in Python 3.2, but this class can be copy pasted into
+ user code for use with earlier Python versions.
+ """
+
+ def __init__(self, queue):
+ """
+ Initialise an instance, using the passed queue.
+ """
+ logging.Handler.__init__(self)
+ self.queue = queue
+
+ def enqueue(self, record):
+ """
+ Enqueue a record.
+
+ The base implementation uses put_nowait. You may want to override
+ this method if you want to use blocking, timeouts or custom queue
+ implementations.
+ """
+ self.queue.put_nowait(record)
+
+ def emit(self, record):
+ """
+ Emit a record.
+
+ Writes the LogRecord to the queue, preparing it for pickling first.
+ """
+ try:
+ # The format operation gets traceback text into record.exc_text
+ # (if there's exception data), and also puts the message into
+ # record.message. We can then use this to replace the original
+ # msg + args, as these might be unpickleable. We also zap the
+ # exc_info attribute, as it's no longer needed and, if not None,
+ # will typically not be pickleable.
+ self.format(record)
+ record.msg = record.message
+ record.args = None
+ record.exc_info = None
+ self.enqueue(record)
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ self.handleError(record)