from enum import Enum from typing import Optional from lib.data.ourtime.ourtime import OurTime from lib.core.pathlib.pathlib import Path class LogType(Enum): STDOUT = "stdout" ERROR = "error" class LogItemArgs: def __init__(self, cat: str, log: str, logtype: LogType, timestamp: Optional[OurTime] = None): self.timestamp = timestamp self.cat = cat self.log = log self.logtype = logtype import os from lib.core.texttools.texttools import name_fix, expand, dedent from lib.data.ourtime.ourtime import OurTime, now as ourtime_now class Logger: def __init__(self, path: Path, lastlog_time: int = 0): self.path = path self.lastlog_time = lastlog_time def log(self, args_: LogItemArgs): args = args_ t = args.timestamp if args.timestamp else ourtime_now() # Format category (max 10 chars, ascii only) args.cat = name_fix(args.cat) if len(args.cat) > 10: raise ValueError('category cannot be longer than 10 chars') args.cat = expand(args.cat, 10, ' ') args.log = dedent(args.log).strip() logfile_path = os.path.join(self.path.path, f"{t.dayhour()}.log") # Create log file if it doesn't exist if not os.path.exists(logfile_path): with open(logfile_path, 'w') as f: pass # Create empty file self.lastlog_time = 0 # make sure we put time again with open(logfile_path, 'a') as f: content = '' # Add timestamp if we're in a new second if t.unix() > self.lastlog_time: content += f"\n{t.time().format_ss()}\n" self.lastlog_time = t.unix() # Format log lines error_prefix = 'E' if args.logtype == LogType.ERROR else ' ' lines = args.log.split('\n') for i, line in enumerate(lines): if i == 0: content += f"{error_prefix} {args.cat} - {line}\n" else: content += f"{error_prefix} {line}\n" f.write(content.rstrip()) # Use rstrip to remove trailing whitespace f.write('\n') # Add a newline after each log entry for consistency class LogItem: def __init__(self, timestamp: OurTime, cat: str, log: str, logtype: LogType): self.timestamp = timestamp self.cat = cat self.log = log self.logtype = logtype