100 lines
3.5 KiB
Python
100 lines
3.5 KiB
Python
__author__ = 'Wendell Jones'
|
|
|
|
import logging
|
|
from logging.handlers import RotatingFileHandler
|
|
import time
|
|
from datetime import datetime, timedelta
|
|
import os
|
|
from glob import glob
|
|
import math as m
|
|
|
|
|
|
class Logger:
|
|
def __init__(self):
|
|
pass
|
|
|
|
def __del__(self):
|
|
pass
|
|
|
|
|
|
class LPrint:
|
|
def __init__(self, log_dir, force_rotate):
|
|
self.log_dir = log_dir
|
|
self.logfile = os.path.join(log_dir, 'dbsync.log')
|
|
self.setup_logfile()
|
|
self.cleanup_old_logs()
|
|
self.check_log_size(force_rotate)
|
|
|
|
def setup_logfile(self):
|
|
"""Ensure the logfile exists and is ready for use."""
|
|
os.makedirs(self.log_dir, exist_ok=True)
|
|
with open(self.logfile, 'a'):
|
|
os.utime(self.logfile, None)
|
|
|
|
def cleanup_old_logs(self):
|
|
"""Remove log files older than 14 days."""
|
|
logfile_list = glob(f'{self.logfile}.*')
|
|
date_limit = datetime.today() - timedelta(days=14)
|
|
for log in logfile_list:
|
|
timestamp = datetime.fromtimestamp(os.path.getmtime(log))
|
|
if timestamp < date_limit:
|
|
os.remove(log)
|
|
|
|
def check_log_size(self, force_rotate):
|
|
"""Check the log file size and rotate if necessary."""
|
|
log_size = os.path.getsize(self.logfile)
|
|
print(f'Logfile Size: {log_size} ({self.humanbytes(log_size)})')
|
|
if force_rotate or log_size > 10_000_000: # 10 MB
|
|
self.rotate_logs()
|
|
|
|
def rotate_logs(self):
|
|
"""Rotate the log file."""
|
|
from logrotater import LogRotate # Assuming logrotater is a custom module
|
|
rotater = LogRotate(prefix=self.logfile, verbose=True)
|
|
try:
|
|
rotater.rotate()
|
|
except FileExistsError as e:
|
|
print(f'Unable to overwrite archive log: {e}. Deleting old logs.')
|
|
for log in glob(f'{self.logfile}.*'):
|
|
try:
|
|
os.remove(log)
|
|
except Exception as e:
|
|
print(f'Unable to delete {log}: {e}')
|
|
|
|
def start_log(self):
|
|
"""Initialize logging."""
|
|
logging.basicConfig(filename=self.logfile, level=logging.DEBUG)
|
|
|
|
def logprint(self, loglevel, logmessage):
|
|
"""Log a message with a timestamp."""
|
|
logstamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
log_message = f'{logstamp}: {logmessage}'
|
|
loglevel = loglevel.lower()
|
|
if loglevel == 'debug':
|
|
logging.debug(log_message)
|
|
elif loglevel == 'warning':
|
|
logging.warning(log_message)
|
|
elif loglevel == 'info':
|
|
logging.info(log_message)
|
|
else:
|
|
logging.error(f'Unknown log level: {loglevel}. Message: {logmessage}')
|
|
|
|
def create_rotating_log(self, logpath, max_bytes=10_000_000, backup_count=5):
|
|
"""Create a rotating log handler."""
|
|
logger = logging.getLogger("Rotating Log")
|
|
logger.setLevel(logging.INFO)
|
|
handler = RotatingFileHandler(logpath, maxBytes=max_bytes, backupCount=backup_count)
|
|
logger.addHandler(handler)
|
|
|
|
@staticmethod
|
|
def humanbytes(size, binary=False, precision=2):
|
|
"""Convert bytes to a human-readable format."""
|
|
multiples = ["B", "k{}B", "M{}B", "G{}B", "T{}B", "P{}B", "E{}B", "Z{}B", "Y{}B"]
|
|
base = 1024 if binary else 1000
|
|
multiple = m.trunc(m.log2(size) / m.log2(base)) if size > 0 else 0
|
|
value = size / m.pow(base, multiple) if size > 0 else 0
|
|
suffix = multiples[multiple].format("i" if binary else "")
|
|
return f"{value:.{precision}f} {suffix}"
|
|
|
|
def __del__(self):
|
|
pass |