Как мне записать X-Forwarded-For с помощью журнала fastapi?

Я запускаю 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 экземпляра fastapi на 2 серверах, работающих за haproxy. Мне удалось добавить эту опцию в haproxy для перехода по IP-адресу клиента к моему API:

option forwardfor

Я могу подтвердить с помощью TCPDUMP на одном из серверов API, что я действительно получаю некоторые заголовки x-fwd:

[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*

Но в моих журналах я вижу только IP-адрес vip, на который попали запросы, хотя HAproxy изменяет IP-адрес клиента, я не могу его зарегистрировать.

Есть ли настраиваемая переменная, которую я могу использовать для раздела доступа log_config?

Спасибо.


person ScipioAfricanus    schedule 08.02.2021    source источник


Ответы (2)


Вы можете использовать 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

person Gabriel Cappelli    schedule 28.02.2021
comment
Я добавил это в. Журнал доступа, кажется, все еще показывает IP VIP. Можно ли использовать другую переменную для форматера? Вот что у меня сейчас есть: 31 (): uvicorn.logging.AccessFormatter, 33 fmt: '% (asctime) s ::% (levelprefix) s% (client_addr) s -% (request_line) s% (status_code) s' , - person ScipioAfricanus; 28.02.2021
comment
Да, в документации, которую я вам отправил, объясняется, что вам также необходимо использовать --forwarded-allow-ips, если ваш трафик не исходит от 127.0.0.1 - person Gabriel Cappelli; 01.03.2021
comment
Спасибо за направление, которое у меня получилось. - person ScipioAfricanus; 02.03.2021

Хорошо, я разобрался.

Мне пришлось включить в start.py 2 вещи:

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"
    )
person ScipioAfricanus    schedule 28.02.2021