如何使用 fastapi 日志记录捕获 X-Forwarded-For?
How do I capture X-Forwarded-For with fastapi logging?
我是 运行 FastApi 和 guvicorn 在这样的函数中:
if __name__ == "__main__":
uvicorn.run(
app="app.main:app",
host="HOSTIP",
port=8000,
reload=True,
# log_config=None,
log_config=log_config,
log_level="info"
)
这是我的 log_config 的样子:
log_config = {
"version": 1,
"disable_existing_loggers": True,
"formatters": {
"default": {
"()": "uvicorn.logging.DefaultFormatter",
"fmt": "%(asctime)s::%(levelname)s::%(name)s::%(filename)s::%(funcName)s - %(message)s",
"use_colors": None,
},
"access": {
"()": "uvicorn.logging.AccessFormatter",
"fmt": '%(asctime)s::%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s',
},
},
"handlers":
{
"default":
{
"formatter": "default",
# "class": 'logging.NullHandler',
"class": 'logging.FileHandler',
"filename": CONFIG[SECTION]["default"]
},
"error":
{
"formatter": "default",
# "class": 'logging.NullHandler',
"class": 'logging.FileHandler',
"filename": CONFIG[SECTION]["error"]
},
"access":
{
"formatter": "access",
# "class": 'logging.NullHandler',
"class": 'logging.FileHandler',
"filename": CONFIG[SECTION]["access"]
},
},
"loggers":
{
"uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False},
"uvicorn.error": {"handlers": ["error"], "level": "ERROR", "propagate": False},
"uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": False},
}
}
我在 2 台服务器上有 2 个 fastapi 实例,运行 在 haproxy 后面。我能够在 haproxy 中加入这个选项,将客户端 IP 转发到我的 API:
option forwardfor
我能够在其中一台 API 服务器上使用 TCPDUMP 确认我实际上正在接收一些 x-fwd headers 进来:
[user@server ~]# tcpdump -i INTERFACE host SERVERIP -AAA | grep -i IP OF MY LAPTOP
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on INTERFACE, link-type EN10MB (Ethernet), capture size 262144 bytes
*X-Forwarded-For: IP OF MY LAPTOP*
但是在我的日志中,我只看到请求命中的 vip 的 IP,即使 HAproxy 正在转发客户端的 IP,我也无法记录它。
是否有可用于 log_config 访问部分的自定义变量?
谢谢。
您可以使用 proxy_headers=True
填充远程地址信息:
来自文档:
--proxy-headers / --no-proxy-headers
Enable/Disable X-Forwarded-Proto,
X-Forwarded-For, X-Forwarded-Port to
populate remote address info.
https://www.uvicorn.org/deployment/#running-from-the-command-line
好的,我明白了。
我必须在 start.py 中包含两件事:
if __name__ == "__main__":
uvicorn.run(
app="app.main:app",
host="HOSTIP",
port=8000,
reload=True,
proxy_headers=True, # THIS LINE
forwarded_allow_ips='*', # THIS LINE
log_config=log_config,
log_level="info"
)
我是 运行 FastApi 和 guvicorn 在这样的函数中:
if __name__ == "__main__":
uvicorn.run(
app="app.main:app",
host="HOSTIP",
port=8000,
reload=True,
# log_config=None,
log_config=log_config,
log_level="info"
)
这是我的 log_config 的样子:
log_config = {
"version": 1,
"disable_existing_loggers": True,
"formatters": {
"default": {
"()": "uvicorn.logging.DefaultFormatter",
"fmt": "%(asctime)s::%(levelname)s::%(name)s::%(filename)s::%(funcName)s - %(message)s",
"use_colors": None,
},
"access": {
"()": "uvicorn.logging.AccessFormatter",
"fmt": '%(asctime)s::%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s',
},
},
"handlers":
{
"default":
{
"formatter": "default",
# "class": 'logging.NullHandler',
"class": 'logging.FileHandler',
"filename": CONFIG[SECTION]["default"]
},
"error":
{
"formatter": "default",
# "class": 'logging.NullHandler',
"class": 'logging.FileHandler',
"filename": CONFIG[SECTION]["error"]
},
"access":
{
"formatter": "access",
# "class": 'logging.NullHandler',
"class": 'logging.FileHandler',
"filename": CONFIG[SECTION]["access"]
},
},
"loggers":
{
"uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False},
"uvicorn.error": {"handlers": ["error"], "level": "ERROR", "propagate": False},
"uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": False},
}
}
我在 2 台服务器上有 2 个 fastapi 实例,运行 在 haproxy 后面。我能够在 haproxy 中加入这个选项,将客户端 IP 转发到我的 API:
option forwardfor
我能够在其中一台 API 服务器上使用 TCPDUMP 确认我实际上正在接收一些 x-fwd headers 进来:
[user@server ~]# tcpdump -i INTERFACE host SERVERIP -AAA | grep -i IP OF MY LAPTOP
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on INTERFACE, link-type EN10MB (Ethernet), capture size 262144 bytes
*X-Forwarded-For: IP OF MY LAPTOP*
但是在我的日志中,我只看到请求命中的 vip 的 IP,即使 HAproxy 正在转发客户端的 IP,我也无法记录它。
是否有可用于 log_config 访问部分的自定义变量?
谢谢。
您可以使用 proxy_headers=True
填充远程地址信息:
来自文档:
--proxy-headers / --no-proxy-headers
Enable/Disable X-Forwarded-Proto,
X-Forwarded-For, X-Forwarded-Port to
populate remote address info.
https://www.uvicorn.org/deployment/#running-from-the-command-line
好的,我明白了。
我必须在 start.py 中包含两件事:
if __name__ == "__main__":
uvicorn.run(
app="app.main:app",
host="HOSTIP",
port=8000,
reload=True,
proxy_headers=True, # THIS LINE
forwarded_allow_ips='*', # THIS LINE
log_config=log_config,
log_level="info"
)