[Python-ideas] Logging: a more perseverent version of the StreamHandler?
liam.marsh.home at gmail.com
Fri Jan 26 15:46:51 EST 2018
Some time ago, I set up some logging using stdout in a program with the
`stdout_redirected()` context manager, which had to close and reopen
stdout to work.
Unsurprisingly, the StreamHandler didn't take it well.
So I made a Handler class which is able to reload the stream (AKA get
the new sys.stdout) whenever the old one wasn't writable.
But there might be some more legit use cases for stubborn StreamHandlers
like that (that are not ugly-looking, hopefully temporary patches).
The way I see it for now is a StreamHandler subclass which, instead of
having a `stream` argument, would have |`getStream`|,|`reloadStream`|
and |`location`|, and would be used this way:
On initialisation, it would load the stream object, then act as a
regular StreamHandler, but checking that the stream is writable at each
`handler.emit()` call. If it is not, then reload it.
If given, the |`getStream`| (a callable object which returns a
ready-to-use stream) argument is used to load/reload the underlying
stream, else it would be fetched at the location described by
`location`, and, if it is still not writable, call |`reloadStream()`
|(which should put a usable stream object at |`location`|) then try to
fetch it again.
Here is the current implementation I have:
from .config import _resolve as resolve # will (uglily) be used later
| A stream handler which reloads the stream object from one place if
an error occurs|
| def __init__(self, getStream=None, reloadStream=None, location=None):|
| Initialize the handler.|
| If stream is not specified, sys.stderr is used.|
self.getStream = getStream
self.stream = None # to be overwritten later
if getStream is None:|
|| if location is None:
self.location = 'sys.stderr' # note the lack of 'ext://'
self.reloadStream = None
| self.reloadStream = reloadStream
self.location = location
stream = self.reload() # gets the stream
if self.getStream is not None:
stream = self.getStream()
stream = resolve(self.location)
exc = None
except Exception as err:
exc = err # is this really needed?
stream = None # just retry for now
if stream is None or not stream.writable():
if self.reloadStream is None:
raise ValueError("ReloadingHandler couldn't
reload a valid stream")
stream = resolve(self.location) # if it fails this
time, do not catch exception here
| def emit(self, record):|
| Emit a record.|
| If a formatter is specified, it is used to format the record.|
| The record is then written to the stream with a trailing
| exception information is present, it is formatted using|
| traceback.print_exception and appended to the stream. If the
| has an 'encoding' attribute, it is used to determine how to do the|
| output to the stream.|
| if not self.stream.writable():|
| StreamHandler.emit(self, record)|
What do you think? (about the idea, the implementation, and the way I
wrote this email)|
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Python-ideas