Logging
logger
¶
TextFormatter
¶
TextFormatter(
fmt: str = "[%(asctime)s] | %(pathname)s:%(lineno)d | %(levelname)s | %(message)s",
datefmt: str = "%Y-%m-%d %H:%M:%S",
use_colors: bool = True,
)
DailyRotatingFileHandler
¶
DailyRotatingFileHandler(
filename: str | PathLike[str],
mode: str = "a",
max_bytes: int = 10 * 1024 * 1024,
backup_count: int = 5,
encoding: str | None = "utf-8",
delay: bool = False,
errors: str | None = None,
structured: bool = True,
*,
folder: Path | str = "logs",
)
Bases: RotatingFileHandler
A file handler that writes log messages to daily rotating files.
Source code in pokelance/logger.py
def __init__(
self,
filename: str | os.PathLike[str],
mode: str = "a",
max_bytes: int = 10 * 1024 * 1024,
backup_count: int = 5,
encoding: str | None = "utf-8",
delay: bool = False,
errors: str | None = None,
structured: bool = True,
*,
folder: pathlib.Path | str = "logs",
) -> None:
self._last_entry = datetime.datetime.now(datetime.timezone.utc)
self.folder = pathlib.Path(folder)
self.filename = filename
self.folder.mkdir(exist_ok=True)
super().__init__(
self.folder / f"{datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d')}-{self.filename}.log",
mode=mode,
maxBytes=max_bytes,
backupCount=backup_count,
encoding=encoding,
delay=delay,
errors=errors,
)
self.setFormatter(JSONFormatter(use_colors=False) if structured else TextFormatter(use_colors=False))
self.addFilter(RelativePathFilter())
emit
¶
emit(record: LogRecord) -> None
Emit a log record.
Source code in pokelance/logger.py
@override
def emit(self, record: logging.LogRecord) -> None:
"""Emit a log record."""
now = datetime.datetime.now(datetime.timezone.utc)
if self._last_entry.date() != now.date():
self._last_entry = now
self.close()
self.baseFilename = (
self.folder / f"{self._last_entry.strftime('%Y-%m-%d')}-{self.filename}.log"
).as_posix()
self.stream = self._open()
super().emit(record)
handle_exception
¶
handle_exception(
exc_type: type[BaseException],
exc_value: BaseException,
exc_traceback: TracebackType | None,
) -> None
Global unhandled exception hook handler.
Source code in pokelance/logger.py
def handle_exception(
exc_type: type[BaseException], exc_value: BaseException, exc_traceback: TracebackType | None
) -> None:
"""Global unhandled exception hook handler."""
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logger.critical("Unhandled exception", exc_info=(exc_type, exc_value, exc_traceback))
setup_logging
¶
setup_logging(
log_level: int = INFO,
structured: bool = False,
file_logging: bool = False,
filename: str = "pokelance",
log_dir: str | Path = "logs",
set_excepthook: bool = True,
) -> None
Set up logging for console and optional file handlers on pokelance namespace.
Source code in pokelance/logger.py
def setup_logging(
log_level: int = logging.INFO,
structured: bool = False,
file_logging: bool = False,
filename: str = "pokelance",
log_dir: str | pathlib.Path = "logs",
set_excepthook: bool = True,
) -> None:
"""Set up logging for console and optional file handlers on pokelance namespace."""
console_formatter = "json_colored" if structured else "text_colored"
file_formatter = "json_plain" if structured else "text_plain"
handlers: dict[str, dict[str, t.Any]] = {
"console": {
"class": "logging.StreamHandler",
"level": log_level,
"formatter": console_formatter,
"filters": ["relative_path"],
"stream": "ext://sys.stderr",
},
}
if file_logging:
handlers["file"] = {
"()": DailyRotatingFileHandler,
"level": log_level,
"formatter": file_formatter,
"filename": filename,
"folder": str(log_dir),
"structured": structured,
}
logging_config: dict[str, t.Any] = {
"version": 1,
"disable_existing_loggers": False,
"filters": {
"relative_path": {
"()": RelativePathFilter,
},
},
"formatters": {
"text_colored": {
"()": TextFormatter,
"use_colors": True,
},
"text_plain": {
"()": TextFormatter,
"use_colors": False,
},
"json_colored": {
"()": JSONFormatter,
"use_colors": True,
},
"json_plain": {
"()": JSONFormatter,
"use_colors": False,
},
},
"handlers": handlers,
"loggers": {
"pokelance": {
"handlers": list(handlers.keys()),
"level": log_level,
"propagate": False,
},
},
}
logging.config.dictConfig(logging_config)
if set_excepthook:
sys.excepthook = handle_exception