Sanic 使用 Loguru 替换默认的 LOGGING

Sanic 默认是通过 LOGGING来记录日志的,目前日志记录多半使用Loguru,且Loguru支持LOGGING接口,因此我们选择将LOGGING用Loguru替代。

以下代码兼容多workers,兼容sqlalchemy等,不会导致重复打印。

原理:注册InterceptHandler,接管日志打印。

根目录下的logger.py:

import logging
import sys
from typing import Dict, Any

from loguru import logger

LOG_FORMAT = '{time:YYYY-MM-DD HH:mm:ss} [{level}] {module}:{name}:{line} - {message}'

logger.add("info.log", filter=lambda record: "INFO" in record['level'].name, rotation="10 MB",
           retention="3 days", level="INFO", format=LOG_FORMAT)
logger.add("trace.log", filter=lambda record: "TRACE" in record['level'].name, level="TRACE")
logger.add("debug.log", filter=lambda record: "DEBUG" in record['level'].name, rotation="10 MB",
           retention="3 days", level="DEBUG", format=LOG_FORMAT)
logger.add("error.log", filter=lambda record: "ERROR" in record['level'].name, rotation="10 MB",
           retention="1 days", level="ERROR", format=LOG_FORMAT)

S_LOGGING_CONFIG_DEFAULTS: Dict[str, Any] = dict(  # no cov
    version=1,
    disable_existing_loggers=False,
    loggers={
        "sanic.root": {"level": "INFO", "handlers": ["console"], "propagate": False},
        "sanic.error": {
            "level": "INFO",
            "handlers": ["error_console"],
            "propagate": False,
            "qualname": "sanic.error",
        },
        "sanic.access": {
            "level": "INFO",
            "handlers": ["access_console"],
            "propagate": False,
            "qualname": "sanic.access",
        },
        "sanic.server": {
            "level": "INFO",
            "handlers": ["console"],
            "propagate": False,
            "qualname": "sanic.server",
        },
    },
    handlers={
        "console": {
            "class": "logger.InterceptHandler",
        },
        "error_console": {
            "class": "logger.InterceptHandler",
        },
        "access_console": {
            "class": "logger.InterceptHandler",
        },
    }
)


class InterceptHandler(logging.Handler):
    def emit(self, record: logging.LogRecord):
        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 setup_log():
    logging.root.handlers = [InterceptHandler()]
    logging.root.setLevel("DEBUG")
    for name in logging.root.manager.loggerDict.keys():
        logging.getLogger(name).handlers = []
        logging.getLogger(name).propagate = True
    logger.configure(handlers=[{"sink": sys.stdout, "serialize": False}])

配置文件:

S_LOGGING_CONFIG_DEFAULTS: Dict[str, Any] = dict(  # no cov
    version=1,
    disable_existing_loggers=False,
    loggers={
        "sanic.root": {"level": "INFO", "handlers": ["console"],"propagate": False},
        "sanic.error": {
            "level": "INFO",
            "handlers": ["error_console"],
            "propagate": False,
            "qualname": "sanic.error",
        },
        "sanic.access": {
            "level": "INFO",
            "handlers": ["access_console"],
            "propagate": False,
            "qualname": "sanic.access",
        },
        "sanic.server": {
            "level": "INFO",
            "handlers": ["console"],
            "propagate": False,
            "qualname": "sanic.server",
        },
    },
    handlers={
        "console": {
            "class": "logger.InterceptHandler",
        },
        "error_console": {
            "class": "logger.InterceptHandler",
        },
        "access_console": {
            "class": "logger.InterceptHandler",
        },
    }
)

说明,Access Log未作特别处理,感觉也用不到,如果你需要记录访问日志建议用别的方式实现,如nginx。

上面的handlers是我自己根目录下的logger.py,自己的路径自己替换下。

APP启动方式:

确保先setup_log,再创建sanic app,且要配置log_config。

setup_log()
app = Sanic('demo-app', log_config=S_LOGGING_CONFIG_DEFAULTS)

app内需要使用日志时,可以直接使用sanic.log下的logger,正常打印即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值