Files
LoveACE-EndF/loveace/utils/richuru_hook.py

108 lines
3.6 KiB
Python
Raw Permalink Normal View History

import logging
import os
import sys
import types
from datetime import datetime
from logging import LogRecord
from pathlib import Path
from typing import Callable, Iterable, List, Optional, Union
from loguru import logger
from rich.console import Console, ConsoleRenderable
from rich.text import Text
from rich.theme import Theme
from rich.traceback import Traceback
from richuru import ExceptionHook, LoguruHandler, LoguruRichHandler, _loguru_exc_hook
class HookedLoguruRichHandler(LoguruRichHandler):
"""
A hooked version of LoguruRichHandler to fix some issues.
"""
def render(
self,
*,
record: LogRecord,
traceback: Optional[Traceback],
message_renderable: "ConsoleRenderable",
) -> "ConsoleRenderable":
"""Render log for display.
Args:
record (LogRecord): logging Record.
traceback (Optional[Traceback]): Traceback instance or None for no Traceback.
message_renderable (ConsoleRenderable): Renderable (typically Text) containing log message contents.
Returns:
ConsoleRenderable: Renderable to display log.
"""
current_path = Path(os.getcwd())
path = Path(record.pathname)
try:
path = path.relative_to(current_path)
if sys.platform == "win32":
path = str(path).replace("\\", "/")
except ValueError:
path = Path(record.pathname).name
path = str(path)
level = self.get_level_text(record)
time_format = None if self.formatter is None else self.formatter.datefmt
log_time = datetime.fromtimestamp(record.created)
log_renderable = self._log_render(
self.console,
[message_renderable] if not traceback else [message_renderable, traceback],
log_time=log_time,
time_format=time_format,
level=level,
path=path,
line_no=record.lineno,
link_path=record.pathname if self.enable_link_path else None,
)
return log_renderable
def install(
rich_console: Optional[Console] = None,
exc_hook: Optional[ExceptionHook] = _loguru_exc_hook,
rich_traceback: bool = True,
tb_ctx_lines: int = 3,
tb_theme: Optional[str] = None,
tb_suppress: Iterable[Union[str, types.ModuleType]] = (),
time_format: Union[str, Callable[[datetime], Text]] = "[%x %X]",
keywords: Optional[List[str]] = None,
level: Union[int, str] = 20,
) -> None:
"""Install Rich logging and Loguru exception hook"""
logging.basicConfig(handlers=[LoguruHandler()], level=0)
logger.configure(
handlers=[
{
"sink": HookedLoguruRichHandler(
console=rich_console
or Console(
theme=Theme(
{
"logging.level.success": "green",
"logging.level.trace": "bright_black",
}
)
),
rich_tracebacks=rich_traceback,
tracebacks_show_locals=True,
tracebacks_suppress=tb_suppress,
tracebacks_extra_lines=tb_ctx_lines,
tracebacks_theme=tb_theme,
show_time=False,
log_time_format=time_format,
keywords=keywords,
),
"format": (lambda _: "{message}") if rich_traceback else "{message}",
"level": level,
}
]
)
if exc_hook is not None:
sys.excepthook = exc_hook