1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| import os import sys import time import logging from types import FrameType from typing import cast from loguru import logger from .path_conf import LogPath
class Logger: """输出日志到文件和控制台"""
def __init__(self): log_name = f"Fast_{time.strftime('%Y-%m-%d', time.localtime()).replace('-', '_')}.log" log_path = os.path.join(LogPath, "Fast_{time:YYYY-MM-DD}.log") self.logger = logger self.logger.remove() if not os.path.exists(LogPath): os.makedirs(LogPath) formatter = "{time:YYYY-MM-DD HH:mm:ss} | {level}: {message}" self.logger.add(sys.stdout, format="<green>{time:YYYYMMDD HH:mm:ss}</green> | " "{process.name} | " "{thread.name} | " "<cyan>{module}</cyan>.<cyan>{function}</cyan>" ":<cyan>{line}</cyan> | " "<level>{level}</level>: " "<level>{message}</level>", ) self.logger.add(log_path, format='{time:YYYYMMDD HH:mm:ss} - ' "{process.name} | " "{thread.name} | " '{module}.{function}:{line} - {level} -{message}', encoding='utf-8', retention='7 days', backtrace=True, diagnose=True, enqueue=True, rotation="00:00", )
def init_config(self): LOGGER_NAMES = ("uvicorn.asgi", "uvicorn.access", "uvicorn")
logging.getLogger().handlers = [InterceptHandler()] for logger_name in LOGGER_NAMES: logging_logger = logging.getLogger(logger_name) logging_logger.handlers = [InterceptHandler()]
def get_logger(self): return self.logger
class InterceptHandler(logging.Handler): def emit(self, record: logging.LogRecord) -> None: try: level = logger.level(record.levelname).name except ValueError: level = str(record.levelno)
frame, depth = logging.currentframe(), 2 while frame.f_code.co_filename == logging.__file__: frame = cast(FrameType, frame.f_back) depth += 1
logger.opt(depth=depth, exception=record.exc_info).log( level, record.getMessage(), )
Loggers = Logger() log = Loggers.get_logger()
|