FastAPI gunicorn 添加一个日志记录时间戳
FastAPI gunicorn add a logging timestamp
我正在使用 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的logger格式?
您应该能够使用 uvicorn-gunicorn docker 图像中使用的 access_log_format
variable in your gunicorn_conf.py
file. You can base your gunicorn_conf.py
file this one 修改访问日志的格式。
我相信 access_log_format
选项在使用 uvicorn/gunicorn/fastapi 组合时是 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 答案以获得日志记录字典配置的一些很好的示例。
如果您真的想编辑 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
header 值感兴趣。一个丑陋的解决方法是猴子补丁 uvicorn.protocols.utils.get_client_addr
并从传递给它的 scope
字典中拉出你想要的任何东西。它恰好有请求headers。注意:这可能会产生意想不到的后果,特别是如果 uvicorn
的人将他们的代码更改为使用 get_client_addr
而不是打印值。
也许有一种方法可以通过使用自定义记录器的自定义工作器 class 来完成此操作,但我也还没有看到这样做。
我正在使用 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的logger格式?
您应该能够使用 uvicorn-gunicorn docker 图像中使用的 access_log_format
variable in your gunicorn_conf.py
file. You can base your gunicorn_conf.py
file this one 修改访问日志的格式。
我相信 access_log_format
选项在使用 uvicorn/gunicorn/fastapi 组合时是 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 答案以获得日志记录字典配置的一些很好的示例。
如果您真的想编辑 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
header 值感兴趣。一个丑陋的解决方法是猴子补丁 uvicorn.protocols.utils.get_client_addr
并从传递给它的 scope
字典中拉出你想要的任何东西。它恰好有请求headers。注意:这可能会产生意想不到的后果,特别是如果 uvicorn
的人将他们的代码更改为使用 get_client_addr
而不是打印值。
也许有一种方法可以通过使用自定义记录器的自定义工作器 class 来完成此操作,但我也还没有看到这样做。