Make log rotation also limited by size and controllable from settings. Resolves #2041

This commit is contained in:
Griatch 2020-01-29 23:16:53 +01:00
parent f124b3510b
commit ff16eb1bfe
13 changed files with 98 additions and 40 deletions

View file

@ -16,6 +16,7 @@ log_typemsg(). This is for historical, back-compatible reasons.
import os
import time
import glob
from datetime import datetime
from traceback import format_exc
from twisted.python import log, logfile
@ -76,33 +77,78 @@ def timeformat(when=None):
class WeeklyLogFile(logfile.DailyLogFile):
"""
Log file that rotates once per week. Overrides key methods to change format
Log file that rotates once per week by default. Overrides key methods to change format.
"""
day_rotation = 7
def __init__(self, name, directory, defaultMode=None, day_rotation=7, max_size=1000000):
"""
Args:
name (str): Name of log file.
directory (str): Directory holding the file.
defaultMode (str): Permissions used to create file. Defaults to
current permissions of this file if it exists.
day_rotation (int): How often to rotate the file.
max_size (int): Max size of log file before rotation (regardless of
time). Defaults to 1M.
"""
self.day_rotation = day_rotation
self.max_size = max_size
self.size = 0
logfile.DailyLogFile.__init__(self, name, directory, defaultMode=defaultMode)
def _openFile(self):
logfile.DailyLogFile._openFile(self)
self.size = self._file.tell()
def shouldRotate(self):
"""Rotate when the date has changed since last write"""
# all dates here are tuples (year, month, day)
now = self.toDate()
then = self.lastDate
return now[0] > then[0] or now[1] > then[1] or now[2] > (then[2] + self.day_rotation)
return (now[0] > then[0] or
now[1] > then[1] or
now[2] > (then[2] + self.day_rotation) or
self.size >= self.max_size)
def suffix(self, tupledate):
"""Return the suffix given a (year, month, day) tuple or unixtime.
Format changed to have 03 for march instead of 3 etc (retaining unix file order)
Format changed to have 03 for march instead of 3 etc (retaining unix
file order)
If we get duplicate suffixes in location (due to hitting size limit),
we append __1, __2 etc.
Examples:
server.log.2020_01_29
server.log.2020_01_29__1
server.log.2020_01_29__2
"""
try:
return "_".join(["{:02d}".format(part) for part in tupledate])
except Exception:
# try taking a float unixtime
return "_".join(["{:02d}".format(part) for part in self.toDate(tupledate)])
suffix = ""
copy_suffix = 0
while True:
try:
suffix = "_".join(["{:02d}".format(part) for part in tupledate])
except Exception:
# try taking a float unixtime
suffix = "_".join(["{:02d}".format(part) for part in self.toDate(tupledate)])
suffix += f"__{copy_suffix}" if copy_suffix else ""
if os.path.exists(f"{self.path}.{suffix}"):
# Append a higher copy_suffix to try to break the tie (starting from 2)
copy_suffix += 1
else:
break
return suffix
def write(self, data):
"Write data to log file"
logfile.BaseLogFile.write(self, data)
self.lastDate = max(self.lastDate, self.toDate())
self.size += len(data)
class PortalLogObserver(log.FileLogObserver):