Skip to content

Instantly share code, notes, and snippets.

@balloob
Last active December 16, 2016 07:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save balloob/fed9600ee1cc009164137c7e3e567835 to your computer and use it in GitHub Desktop.
Save balloob/fed9600ee1cc009164137c7e3e567835 to your computer and use it in GitHub Desktop.
Async friendly logger
class AsyncFileHandler():
def __init__(self, loop, handler):
"""Initialize async logging file handle."""
self.handler = handler
self.loop = loop
self._queue = asyncio.Queue(loop=loop)
self._thread = threading.Thread(target=self._process)
def start_thread(self):
"""Start thread for processing."""
self._thread.start()
def close(self):
"""Close stream and queue."""
self.handler.close()
def emit(self, record):
"""Process a record."""
ident = self.loop.__dict__.get("_thread_ident")
# inside eventloop
if ident is not None and ident == threading.get_ident():
self._queue.put_nowait(record)
# from a thread/executor
else:
self.loop.call_soon_threadsafe(self._queue.put_nowait, record)
def __repr__(self):
"""String name of this."""
level = logging.getLevelName(self.level)
return "<{} {} ({})>".format(
self.__class__.__name__, self.base_filename, level)
def _process(self):
"""Process log in a thread."""
while True:
record = run_coroutine_threadsafe(
self._queue.get(), self.loop).result()
if record is None:
return
self.handler.emit(record)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment