| import logging |
| import re |
| import sys |
| from datetime import timedelta |
| from pathlib import Path |
|
|
| import sentry_sdk.integrations.logging as sentry |
| from loguru import logger as _logger |
|
|
| from hibiapi.utils.config import Config |
|
|
| LOG_FILE = Config["log"]["file"].get_optional(Path) |
| LOG_LEVEL = Config["log"]["level"].as_str().strip().upper() |
| LOG_FORMAT = Config["log"]["format"].as_str().strip() |
|
|
|
|
| class LoguruHandler(logging.Handler): |
| _tag_escape_re = re.compile(r"</?((?:[fb]g\s)?[^<>\s]*)>") |
|
|
| @classmethod |
| def escape_tag(cls, string: str) -> str: |
| return cls._tag_escape_re.sub(r"\\\g<0>", string) |
|
|
| def emit(self, record: logging.LogRecord): |
| try: |
| level = logger.level(record.levelname).name |
| except ValueError: |
| level = record.levelno |
|
|
| frame, depth, message = logging.currentframe(), 2, record.getMessage() |
| while frame.f_code.co_filename == logging.__file__: |
| frame = frame.f_back |
| depth += 1 |
|
|
| logger.opt(depth=depth, exception=record.exc_info, colors=True).log( |
| level, f"<e>{self.escape_tag(message)}</e>" |
| ) |
|
|
|
|
| logger = _logger.opt(colors=True) |
| logger.remove() |
| logger.add( |
| sys.stdout, |
| level=LOG_LEVEL, |
| format=LOG_FORMAT, |
| filter=lambda record: record["level"].no < logging.WARNING, |
| ) |
| logger.add( |
| sys.stderr, |
| level=LOG_LEVEL, |
| filter=lambda record: record["level"].no >= logging.WARNING, |
| format=LOG_FORMAT, |
| ) |
| logger.add(sentry.BreadcrumbHandler(), level=LOG_LEVEL) |
| logger.add(sentry.EventHandler(), level="ERROR") |
|
|
| if LOG_FILE is not None: |
| LOG_FILE.parent.mkdir(parents=True, exist_ok=True) |
|
|
| logger.add( |
| str(LOG_FILE), |
| level=LOG_LEVEL, |
| encoding="utf-8", |
| rotation=timedelta(days=1), |
| ) |
|
|
| logger.level(LOG_LEVEL) |
|
|