From 29909a52917c621680f262bde0018d5189c6b1c6 Mon Sep 17 00:00:00 2001 From: jon Date: Thu, 4 Aug 2022 10:54:01 +0100 Subject: [PATCH] add truncate() method that discards excess log entries --- phew/logging.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/phew/logging.py b/phew/logging.py index e52b959..78f7bcb 100644 --- a/phew/logging.py +++ b/phew/logging.py @@ -9,6 +9,50 @@ def log_file(file): global _log_file _log_file = file +# truncates the log file down to a target size while maintaining +# clean line breaks +def truncate(target): + # get the current size of the log file + size = 0 + try: + size = os.stat(_log_file)[6] + except OSError: + return + # calculate how many bytes we're aiming to discard + discard = size - target + + if discard < 0: + return + + with open(_log_file, "rb") as infile: + # skip a bunch of the input file until we've discarded + # at least enough + while discard > 0: + chunk = infile.read(1024) + discard -= len(chunk) + + with open(_log_file + ".tmp", "wb") as outfile: + # we have a partial chunk to write, try to find a line + # break nearby to split it on + break_position = chunk.find(b"\n", -discard) + if break_position == -1: + break_position = chunk.rfind(b"\n", -discard) + if break_position == -1: + break_position = 0 + outfile.write(chunk[break_position + 1:]) + + # now copy the rest of the file + while True: + chunk = infile.read(1024) + if not chunk: + break + outfile.write(chunk) + + # delete the old file and replace with the new + os.remove(_log_file) + os.rename(_log_file + ".tmp", _log_file) + + def log(level, text): datetime = datetime_string() log_entry = "{0} [{1:8} /{2:>8}] {3}".format(datetime, level, gc.mem_free(), text)