overridden to implement custom flushing strategies.
-.. class:: MemoryHandler(capacity, flushLevel=ERROR, target=None)
+.. class:: MemoryHandler(capacity, flushLevel=ERROR, target=None, flushOnClose=True)
Returns a new instance of the :class:`MemoryHandler` class. The instance is
initialized with a buffer size of *capacity*. If *flushLevel* is not specified,
:const:`ERROR` is used. If no *target* is specified, the target will need to be
- set using :meth:`setTarget` before this handler does anything useful.
+ set using :meth:`setTarget` before this handler does anything useful. If
+ *flushOnClose* is specified as ``False``, then the buffer is *not* flushed when
+ the handler is closed. If not specified or specified as ``True``, the previous
+ behaviour of flushing the buffer will occur when the handler is closed.
+
+ .. versionchanged:: 3.6
+ The *flushOnClose* parameter was added.
.. method:: close()
-# Copyright 2001-2015 by Vinay Sajip. All Rights Reserved.
+# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
Additional handlers for the logging package for Python. The core package is
based on PEP 282 and comments thereto in comp.lang.python.
-Copyright (C) 2001-2015 Vinay Sajip. All Rights Reserved.
+Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.
To use, simply 'import logging.handlers' and log away!
"""
flushing them to a target handler. Flushing occurs whenever the buffer
is full, or when an event of a certain severity or greater is seen.
"""
- def __init__(self, capacity, flushLevel=logging.ERROR, target=None):
+ def __init__(self, capacity, flushLevel=logging.ERROR, target=None,
+ flushOnClose=True):
"""
Initialize the handler with the buffer size, the level at which
flushing should occur and an optional target.
Note that without a target being set either here or via setTarget(),
a MemoryHandler is no use to anyone!
+
+ The ``flushOnClose`` argument is ``True`` for backward compatibility
+ reasons - the old behaviour is that when the handler is closed, the
+ buffer is flushed, even if the flush level hasn't been exceeded nor the
+ capacity exceeded. To prevent this, set ``flushOnClose`` to ``False``.
"""
BufferingHandler.__init__(self, capacity)
self.flushLevel = flushLevel
self.target = target
+ # See Issue #26559 for why this has been added
+ self.flushOnClose = flushOnClose
def shouldFlush(self, record):
"""
def close(self):
"""
- Flush, set the target to None and lose the buffer.
+ Flush, if appropriately configured, set the target to None and lose the
+ buffer.
"""
try:
- self.flush()
+ if self.flushOnClose:
+ self.flush()
finally:
self.acquire()
try:
def setUp(self):
BaseTest.setUp(self)
self.mem_hdlr = logging.handlers.MemoryHandler(10, logging.WARNING,
- self.root_hdlr)
+ self.root_hdlr)
self.mem_logger = logging.getLogger('mem')
self.mem_logger.propagate = 0
self.mem_logger.addHandler(self.mem_hdlr)
self.mem_logger.debug(self.next_message())
self.assert_log_lines(lines)
+ def test_flush_on_close(self):
+ """
+ Test that the flush-on-close configuration works as expected.
+ """
+ self.mem_logger.debug(self.next_message())
+ self.assert_log_lines([])
+ self.mem_logger.info(self.next_message())
+ self.assert_log_lines([])
+ self.mem_logger.removeHandler(self.mem_hdlr)
+ # Default behaviour is to flush on close. Check that it happens.
+ self.mem_hdlr.close()
+ lines = [
+ ('DEBUG', '1'),
+ ('INFO', '2'),
+ ]
+ self.assert_log_lines(lines)
+ # Now configure for flushing not to be done on close.
+ self.mem_hdlr = logging.handlers.MemoryHandler(10, logging.WARNING,
+ self.root_hdlr,
+ False)
+ self.mem_logger.addHandler(self.mem_hdlr)
+ self.mem_logger.debug(self.next_message())
+ self.assert_log_lines(lines) # no change
+ self.mem_logger.info(self.next_message())
+ self.assert_log_lines(lines) # no change
+ self.mem_logger.removeHandler(self.mem_hdlr)
+ self.mem_hdlr.close()
+ # assert that no new lines have been added
+ self.assert_log_lines(lines) # no change
+
class ExceptionFormatter(logging.Formatter):
"""A special exception formatter."""