In order to buffer logging messages and output them conditionally, you can use a MemoryHandler to decorate the target Handler (i.e. FileHandler or StreamHandler). The signature is logging.handlers.MemoryHandler(capacity, flushLevel=ERROR, target=None, flushOnClose=True) with the argument capacity specifying the buffer size (number of records buffered).
file_handler = logging.FileHandler('test.log', mode='a')
memory_handler = MemoryHandler(capacity, flushLevel=logging.ERROR, target=file_handler, flushOnClose=True)
logger.addHandler(memory_handler)
You can check the source code for the MemoryHandler:
def shouldFlush(self, record):
    """
    Check for buffer full or a record at the flushLevel or higher.
    """
    return (len(self.buffer) >= self.capacity) or \
            (record.levelno >= self.flushLevel)
def flush(self):
    """
    For a MemoryHandler, flushing means just sending the buffered
    records to the target, if there is one. Override if you want
    different behaviour.
    The record buffer is also cleared by this operation.
    """
    self.acquire()
    try:
        if self.target:
            for record in self.buffer:
                self.target.handle(record)
            self.buffer = []
    finally:
        self.release()
def close(self):
    """
    Flush, if appropriately configured, set the target to None and lose the
    buffer.
    """
    try:
        if self.flushOnClose:
            self.flush()
    finally:
        self.acquire()
        try:
            self.target = None
            BufferingHandler.close(self)
        finally:
            self.release()
For more details, have a look at the corresponding section of python logging cookbook.