Implement TimeoutSwitchingFileHandler

This commit is contained in:
Peter J. Holzer 2022-12-03 12:19:00 +01:00
commit 7d8bcbd5bf
2 changed files with 55 additions and 0 deletions

13
README.md Normal file
View File

@ -0,0 +1,13 @@
TimeoutSwitchingFileHandler
===========================
This is a logging file handler for the Python logging system.
It automatically closes the log file after a period of inactivity
(or after the file has been open for some time whichever comes first)
and then opens a new file at the next emit.
This is useful for long-running processes where short periods of
activity alternate with periods of inactivity. Log switchs will
typically occur during inactivity, so each log file will include one
complete active period. Also, since the log files are closed, they can
be safely compressed or removed.

View File

@ -0,0 +1,42 @@
import logging
import threading
import time
class TimeoutSwitchingFileHandler(logging.Handler):
def __init__(self, filename, min_timeout=60, max_timeout=3600):
super().__init__()
self.basename = filename
self.min_timeout = min_timeout
self.max_timeout = max_timeout
self.fh = None
self.last_emit = 0
self.first_emit = 0
self.last_emit = 0
cleanup = threading.Thread(target=self.cleanup_loop, daemon=True)
cleanup.start()
def emit(self, record):
msg = self.format(record)
now = time.time()
if not self.fh:
now_tm = time.localtime(now)
filename = self.basename + time.strftime("%Y-%m-%d-%H-%M-%S", now_tm) + "-%06d" % (now % 1 * 1000000) + ".log"
self.fh = open(filename, "a")
self.first_emit = now
self.fh.write(msg)
self.fh.write("\n")
self.fh.flush()
self.last_emit = now
def cleanup_loop(self):
while True:
time.sleep(1)
self.acquire()
now = time.time()
if self.fh and now - self.last_emit > self.min_timeout:
self.fh.close()
self.fh = None
if self.fh and now - self.first_emit > self.max_timeout:
self.fh.close()
self.fh = None
self.release()