96 lines
2.6 KiB
Python
96 lines
2.6 KiB
Python
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
from datetime import datetime
|
|
from logging.handlers import RotatingFileHandler
|
|
from typing import Optional
|
|
|
|
|
|
LOG_DIR = Path(__file__).parent / "logs"
|
|
LOG_DIR.mkdir(exist_ok=True)
|
|
|
|
|
|
class ColorFormatter(logging.Formatter):
|
|
COLORS = {
|
|
"DEBUG": "\033[36m",
|
|
"INFO": "\033[32m",
|
|
"WARNING": "\033[33m",
|
|
"ERROR": "\033[31m",
|
|
"CRITICAL": "\033[35m",
|
|
}
|
|
RESET = "\033[0m"
|
|
BOLD = "\033[1m"
|
|
|
|
def format(self, record):
|
|
color = self.COLORS.get(record.levelname, "")
|
|
record.levelname = f"{color}{self.BOLD}{record.levelname:8}{self.RESET}"
|
|
return super().format(record)
|
|
|
|
|
|
def get_logger(
|
|
name: str,
|
|
level: int = logging.DEBUG,
|
|
log_file: Optional[str] = None
|
|
) -> logging.Logger:
|
|
logger = logging.getLogger(name)
|
|
logger.setLevel(level)
|
|
|
|
if logger.handlers:
|
|
return logger
|
|
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setLevel(level)
|
|
console_format = ColorFormatter(
|
|
fmt="%(asctime)s | %(levelname)s | %(name)s: %(message)s",
|
|
datefmt="%H:%M:%S"
|
|
)
|
|
console_handler.setFormatter(console_format)
|
|
logger.addHandler(console_handler)
|
|
|
|
file_path = LOG_DIR / (log_file or "ragger.log")
|
|
file_handler = RotatingFileHandler(
|
|
file_path,
|
|
maxBytes=5 * 1024 * 1024,
|
|
backupCount=3,
|
|
encoding="utf-8"
|
|
)
|
|
file_handler.setLevel(level)
|
|
file_format = logging.Formatter(
|
|
fmt="%(asctime)s | %(levelname)-8s | %(name)s: %(message)s",
|
|
datefmt="%Y-%m-%d %H:%M:%S"
|
|
)
|
|
file_handler.setFormatter(file_format)
|
|
logger.addHandler(file_handler)
|
|
|
|
return logger
|
|
|
|
|
|
log = get_logger("ragger")
|
|
|
|
|
|
def log_function_call(func):
|
|
import functools
|
|
|
|
@functools.wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
args_repr = [repr(a) for a in args[:3]]
|
|
kwargs_repr = [f"{k}={v!r}" for k, v in list(kwargs.items())[:3]]
|
|
signature = ", ".join(args_repr + kwargs_repr)
|
|
if len(signature) > 80:
|
|
signature = signature[:77] + "..."
|
|
|
|
log.debug(f"[CALL] {func.__name__}({signature})")
|
|
|
|
try:
|
|
result = func(*args, **kwargs)
|
|
result_repr = repr(result)
|
|
if len(result_repr) > 100:
|
|
result_repr = result_repr[:97] + "..."
|
|
log.debug(f"[RETURN] {func.__name__} -> {result_repr}")
|
|
return result
|
|
except Exception as e:
|
|
log.error(f"[ERROR] {func.__name__}: {type(e).__name__}: {e}")
|
|
raise
|
|
|
|
return wrapper
|