【问题标题】:FastAPI gunicorn add a logging timestampFastAPI gunicorn 添加日志时间戳
【发布时间】:2020-08-18 07:24:54
【问题描述】:

我正在使用 docker 运行 FastAPI https://fastapi.tiangolo.com/deployment/

tiangolo/uvicorn-gunicorn-fastapi:python3.7

start.sh 看起来像:

exec gunicorn -k uvicorn.workers.UvicornWorker -c "$GUNICORN_CONF" "$APP_MODULE"

我的 docker 日志看起来没有时间戳:

INFO:     123.123.123.123:48736 - "GET /wp-login.php HTTP/1.0" 404 Not Found
INFO:     123.123.123.123:48808 - "GET /robots.txt HTTP/1.0" 404 Not Found
INFO:     123.123.123.123:48810 - "GET / HTTP/1.0" 200 OK

似乎在它使用的gunicorn_conf.py

use_loglevel = os.getenv("LOG_LEVEL", "info")

如何轻松优雅地修改带有时间戳的 INFO 和 ERROR 的记录器格式?

【问题讨论】:

    标签: docker logging gunicorn fastapi


    【解决方案1】:

    当使用 uvicorn/gunicorn/fastapi 组合时,我相信 access_log_format 选项是 currently ignored。但这主要是为了编辑日志的%(message)s 部分。如果你只是想添加一个时间戳,你应该能够覆盖记录器的行为(尽管默认值对我来说有一个时间戳)。

    我在定义 fastapi app 之前将下面的示例放在 __init__.py 中。

    import logging, logging.config
    
    LOG_CONFIG = {
        "version": 1,
        "disable_existing_loggers": True,
        "formatters": {"default": {"format": "%(asctime)s [%(process)s] %(levelname)s: %(message)s"}},
        "handlers": {
            "console": {
                "formatter": "default",
                "class": "logging.StreamHandler",
                "stream": "ext://sys.stdout",
                "level": "INFO",
            }
        },
        "root": {"handlers": ["console"], "level": "INFO"},
        "loggers": {
            "gunicorn": {"propagate": True},
            "gunicorn.access": {"propagate": True},
            "gunicorn.error": {"propagate": True},
            "uvicorn": {"propagate": True},
            "uvicorn.access": {"propagate": True},
            "uvicorn.error": {"propagate": True},
        },
    }
    
    logging.config.dictConfig(LOG_CONFIG)
    logger = logging.getLogger(__name__)
    

    查看this 的回答,了解一些关于日志记录 dict 配置的好例子。

    如果您真的想编辑 uvicorn 的访问日志格式,我不确定是否有“官方”方法可以这样做。在撰写本文时,它们似乎具有their code 中的硬编码格式:

                if self.access_log:
                    self.access_logger.info(
                        '%s - "%s %s HTTP/%s" %d',
                        get_client_addr(self.scope),
                        self.scope["method"],
                        get_path_with_query_string(self.scope),
                        self.scope["http_version"],
                        status_code,
                        extra={"status_code": status_code, "scope": self.scope},
                    )
    

    例如,我有兴趣打印 x-forwarded-for 标头值。一种丑陋的解决方法是修改uvicorn.protocols.utils.get_client_addr 并从传递给它的scope dict 中提取您想要的任何内容。它恰好有请求标头。注意:这可能会产生意想不到的后果,特别是如果 uvicorn 的人将他们的代码更改为使用 get_client_addr 来进行除打印值之外的任何事情。

    也许有一种方法可以通过使用自定义记录器的自定义工作类来执行此操作,但我还没有看到这样做。

    【讨论】:

      【解决方案2】:

      您应该能够使用gunicorn_conf.py 文件中的access_log_format 变量修改访问日志的格式。您可以在 uvicorn-gunicorn docker 映像中使用 gunicorn_conf.py 文件 this one

      【讨论】:

      • @user670186 您能否提供有关如何使用 fastapi 进行日志记录的代码示例?我也在使用 docker 但无法获取任何日志。
      • 如果您使用的是 uvicorn/gunicorn btw,我认为 access_log_format 选项目前不起作用:github.com/encode/uvicorn/issues/527
      猜你喜欢
      • 2015-08-30
      • 1970-01-01
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      • 2020-11-03
      • 1970-01-01
      • 1970-01-01
      • 2012-12-24
      相关资源
      最近更新 更多