First Commit
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
"""Rotating log file setup for MailRelay."""
|
||||
|
||||
import logging
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from pathlib import Path
|
||||
|
||||
LOG_PATH = Path(__file__).parent.parent / "data" / "mailrelay.log"
|
||||
LOG_FORMAT = "%(asctime)s [%(levelname)s] %(name)s: %(message)s"
|
||||
MAX_BYTES = 5 * 1024 * 1024 # 5 MB
|
||||
BACKUP_COUNT = 3
|
||||
|
||||
|
||||
def get_logger(name: str) -> logging.Logger:
|
||||
"""Return a named logger wired to the shared rotating file + stderr."""
|
||||
logger = logging.getLogger(name)
|
||||
|
||||
if logger.handlers:
|
||||
return logger # already configured
|
||||
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
# Rotating file handler
|
||||
LOG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
file_handler = RotatingFileHandler(
|
||||
LOG_PATH, maxBytes=MAX_BYTES, backupCount=BACKUP_COUNT, encoding="utf-8"
|
||||
)
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
file_handler.setFormatter(logging.Formatter(LOG_FORMAT))
|
||||
|
||||
# Console handler (INFO and above)
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
console_handler.setFormatter(logging.Formatter(LOG_FORMAT))
|
||||
|
||||
logger.addHandler(file_handler)
|
||||
logger.addHandler(console_handler)
|
||||
|
||||
return logger
|
||||
|
||||
|
||||
def tail_log(lines: int = 50) -> str:
|
||||
"""Return the last N lines of the log file as a string."""
|
||||
if not LOG_PATH.exists():
|
||||
return "(no log file yet)"
|
||||
text = LOG_PATH.read_text(encoding="utf-8")
|
||||
all_lines = text.splitlines()
|
||||
return "\n".join(all_lines[-lines:])
|
||||
Reference in New Issue
Block a user