This repository was archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add a PeriodicallyFlushingMemoryHandler to prevent logging silence #10407
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
65a3755
Add PeriodicallyFlushingMemoryHandler
reivilibre 45d6c07
Use the new handler by default
reivilibre 64b290a
This deserves a comment
reivilibre 9ae01ce
Newsfile
reivilibre 5ab7b48
words!
reivilibre bb94fb0
Update the sample config
reivilibre 0a554ea
Remark thread safety
reivilibre d6b6557
Flush immediately before reactor startup
reivilibre f8c8471
REVIEW: Appease mypy
reivilibre cc31e91
Appease mypy in a better way :)
reivilibre 4fec43f
Now allow use of a custom reactor
reivilibre a82d7c7
Merge branch 'develop' into rei/startup_logging to fix CI
reivilibre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add a buffered logging handler which periodically flushes itself. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import logging | ||
import time | ||
from logging import Handler, LogRecord | ||
from logging.handlers import MemoryHandler | ||
from threading import Thread | ||
from typing import Optional | ||
|
||
from twisted.internet.interfaces import IReactorCore | ||
|
||
|
||
class PeriodicallyFlushingMemoryHandler(MemoryHandler): | ||
""" | ||
This is a subclass of MemoryHandler that additionally spawns a background | ||
thread to periodically flush the buffer. | ||
|
||
This prevents messages from being buffered for too long. | ||
|
||
Additionally, all messages will be immediately flushed if the reactor has | ||
not yet been started. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
capacity: int, | ||
flushLevel: int = logging.ERROR, | ||
target: Optional[Handler] = None, | ||
flushOnClose: bool = True, | ||
period: float = 5.0, | ||
reactor: Optional[IReactorCore] = None, | ||
) -> None: | ||
""" | ||
period: the period between automatic flushes | ||
|
||
reactor: if specified, a custom reactor to use. If not specifies, | ||
defaults to the globally-installed reactor. | ||
Log entries will be flushed immediately until this reactor has | ||
started. | ||
""" | ||
super().__init__(capacity, flushLevel, target, flushOnClose) | ||
|
||
self._flush_period: float = period | ||
self._active: bool = True | ||
self._reactor_started = False | ||
|
||
self._flushing_thread: Thread = Thread( | ||
name="PeriodicallyFlushingMemoryHandler flushing thread", | ||
target=self._flush_periodically, | ||
) | ||
self._flushing_thread.start() | ||
|
||
def on_reactor_running(): | ||
self._reactor_started = True | ||
|
||
reactor_to_use: IReactorCore | ||
if reactor is None: | ||
from twisted.internet import reactor as global_reactor | ||
|
||
reactor_to_use = global_reactor # type: ignore[assignment] | ||
else: | ||
reactor_to_use = reactor | ||
|
||
# call our hook when the reactor start up | ||
reactor_to_use.callWhenRunning(on_reactor_running) | ||
|
||
def shouldFlush(self, record: LogRecord) -> bool: | ||
""" | ||
Before reactor start-up, log everything immediately. | ||
Otherwise, fall back to original behaviour of waiting for the buffer to fill. | ||
""" | ||
|
||
if self._reactor_started: | ||
return super().shouldFlush(record) | ||
else: | ||
return True | ||
|
||
def _flush_periodically(self): | ||
""" | ||
Whilst this handler is active, flush the handler periodically. | ||
""" | ||
|
||
while self._active: | ||
# flush is thread-safe; it acquires and releases the lock internally | ||
self.flush() | ||
time.sleep(self._flush_period) | ||
|
||
def close(self) -> None: | ||
self._active = False | ||
super().close() |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.