106 lines
2.4 KiB
Python
106 lines
2.4 KiB
Python
# logger.py
|
|
|
|
import time
|
|
from typing import Optional
|
|
from dataclasses import dataclass
|
|
|
|
try:
|
|
from colorama import Fore, Style, init as _colorama_init
|
|
_colorama_init(autoreset=True)
|
|
COLOR_ENABLED = True
|
|
except Exception:
|
|
COLOR_ENABLED = False
|
|
|
|
class Fore:
|
|
RED = ""
|
|
YELLOW = ""
|
|
GREEN = ""
|
|
CYAN = ""
|
|
WHITE = ""
|
|
|
|
class Style:
|
|
RESET_ALL = ""
|
|
|
|
START_TIME = time.perf_counter()
|
|
|
|
LEVEL_COLORS = {
|
|
"LOG": Fore.WHITE,
|
|
"INFO": Fore.CYAN,
|
|
"SUCCESS": Fore.GREEN,
|
|
"WARNING": Fore.YELLOW,
|
|
"ERROR": Fore.RED,
|
|
}
|
|
|
|
@dataclass
|
|
class Logger:
|
|
name: str
|
|
to_file: bool = False
|
|
file_path: Optional[str] = None
|
|
stdio: bool = True
|
|
enabled: bool = True
|
|
|
|
def _time_since_start(self) -> float:
|
|
return time.perf_counter() - START_TIME
|
|
|
|
def _format(self, level: str, message: str) -> str:
|
|
t = self._time_since_start()
|
|
prefix = f"[{t:0.3f}][{level}]"
|
|
if COLOR_ENABLED and level in LEVEL_COLORS:
|
|
prefix = f"{LEVEL_COLORS[level]}{prefix}{Style.RESET_ALL}"
|
|
return f"{prefix} {message}"
|
|
|
|
def _write_file(self, text: str):
|
|
if not self.file_path:
|
|
return
|
|
with open(self.file_path, "a", encoding="utf-8") as f:
|
|
f.write(text + "\n")
|
|
|
|
def _log(self, level: str, *args):
|
|
if not self.enabled:
|
|
return
|
|
message = " ".join(str(a) for a in args)
|
|
formatted = self._format(level, message)
|
|
if self.stdio:
|
|
print(formatted)
|
|
if self.to_file:
|
|
clean = f"[{self._time_since_start():0.3f}][{level}] {message}"
|
|
self._write_file(clean)
|
|
|
|
def log(self, *args):
|
|
self._log("LOG", *args)
|
|
|
|
def info(self, *args):
|
|
self._log("INFO", *args)
|
|
|
|
def success(self, *args):
|
|
self._log("SUCCESS", *args)
|
|
|
|
def warning(self, *args):
|
|
self._log("WARNING", *args)
|
|
|
|
def error(self, *args):
|
|
self._log("ERROR", *args)
|
|
|
|
def enable(self):
|
|
self.enabled = True
|
|
|
|
def disable(self):
|
|
self.enabled = False
|
|
|
|
|
|
def create_logger(name: str = "default", toFile: bool = False, path: Optional[str] = None, stdio: bool = True) -> Logger:
|
|
return Logger(
|
|
name=name,
|
|
to_file=toFile,
|
|
file_path=path,
|
|
stdio=stdio,
|
|
enabled=True
|
|
)
|
|
|
|
|
|
logger = create_logger(
|
|
name="main",
|
|
toFile=False,
|
|
stdio=True
|
|
)
|