日志重写

import logging
import os
import sys
from pprint import pformat
from loguru import logger
from config import settings


class InterceptHandler(logging.Handler):
    def emit(self, record):
        # Get corresponding Loguru level if it exists
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno

        # Find caller from where originated the logged message
        frame, depth = logging.currentframe(), 2
        while frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1

        logger.opt(depth=depth, exception=record.exc_info).log(
            level, record.getMessage()
        )


def format_record(record: dict) -> str:
    format_string = settings.config.LOG_FORMAT

    if record["extra"].get("payload") is not None:
        record["extra"]["payload"] = pformat(
            record["extra"]["payload"], indent=4, compact=True, width=88
        )
        format_string += "\n<level>{extra[payload]}</level>"

    format_string += "{exception}\n"
    return format_string


# it requires app init or won't be work
def logger_init():
    log_path_all = os.path.join(settings.config.log_path, settings.config.LOG_FILE)
    log_path_error = os.path.join(settings.config.log_error_path, settings.config.LOG_FILE)
    logging.getLogger().handlers = [InterceptHandler()]
    logger.configure(
        handlers=[{"sink": sys.stdout, "level": logging.DEBUG, "format": format_record}])
    # logger.add(config.LOG_DIR, encoding='utf-8', rotation="9:46")
    logger.add(log_path_all,
               rotation="00:00",
               retention="2 week",
               enqueue=True,
               diagnose=True,
               level="DEBUG",
               format=format_record
               )
    logger.add(log_path_error,
               rotation="00:00",
               retention="3 week",
               enqueue=True,
               backtrace=True,
               diagnose=True,
               level="ERROR",
               format=format_record
               )
    logger.debug('日志系统已加载\n\n\n')
    logging.getLogger("uvicorn.access").handlers = [InterceptHandler()]

在app中调用

app = FastAPI(
    title=config.settings.title,
    debug=config.settings.config.DEBUG
)
# app create frist, then init logger
logger_init()


origins = [
    "http://127.0.0.1",
    f"http://127.0.0.1:{config.settings.config.port}",
    "http://localhost",
    f"http://localhost:{config.settings.config.port}",
    # "*"
]

app.include_router(scraper.router)
app.include_router(works.router)
app.include_router(users.router)
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

if __name__ == '__main__':

    uvicorn.run(
                app='main:app',
                host='0.0.0.0',
                port=config.settings.config.port,
                reload=True,    # should be False at production
                access_log=True,
                ws_ping_interval=300,
                ws_ping_timeout=300
                )