Skip to content

Включение отладки

Возврат отладочной информации в ответах бэкенда

По умолчанию сервер не добавляет детали ошибок в тело ответа, чтобы избежать раскрытия информации, специфичной для экземпляра, конечным пользователям.

Вы можете изменить это, установив:

$ export HORIZON__SERVER__DEBUG=False
$ # запуск бэкенда
$ curl -XPOST http://localhost:8000/failing/endpoint ...
{
    "error": {
        "code": "unknown",
        "message": "Получено необработанное исключение. Пожалуйста, обратитесь в службу поддержки",
        "details": null,
    },
}
$ export HORIZON__SERVER__DEBUG=True
$ # запуск бэкенда
$ curl -XPOST http://localhost:8000/failing/endpoint ...
Traceback (most recent call last):
File ".../uvicorn/protocols/http/h11_impl.py", line 408, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../site-packages/uvicorn/middleware/proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)

ПРЕДУПРЕЖДЕНИЕ

Это только для среды разработки. НЕ используйте в продакшене!

Вывод отладочных логов на бэкенде

См. Настройки логирования, но замените уровень логирования INFO на DEBUG.

Заполнение заголовка X-Request-ID на бэкенде

Сервер может добавить заголовок X-Request-ID к ответам, что позволяет сопоставить запрос на клиенте с ответом бэкенда.

Это делается через промежуточное ПО request_id, которое включено по умолчанию и может быть настроено, как описано ниже:

Bases: BaseModel

X-Request-ID Middleware Settings.

See asgi-correlation-id <https://github.com/snok/asgi-correlation-id>_ documentation.

Examples

.. code-block:: bash

HORIZON__SERVER__REQUEST_ID__ENABLED=True
HORIZON__SERVER__REQUEST_ID__UPDATE_REQUEST_HEADER=True
Source code in horizon/backend/settings/server/request_id.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class RequestIDSettings(BaseModel):
    """X-Request-ID Middleware Settings.

    See `asgi-correlation-id <https://github.com/snok/asgi-correlation-id>`_ documentation.

    Examples
    --------

    .. code-block:: bash

        HORIZON__SERVER__REQUEST_ID__ENABLED=True
        HORIZON__SERVER__REQUEST_ID__UPDATE_REQUEST_HEADER=True
    """

    enabled: bool = Field(default=True, description="Set to ``True`` to enable middleware")
    header_name: str = Field(
        default="X-Request-ID",
        description="Name of response header which is filled up with request ID value",
    )
    update_request_header: bool = Field(
        default=False,
        description=textwrap.dedent(
            """
            If ``False``, bypass header value from request to response as-is.

            If ``True``, always set new value of specific header.
            """,
        ),
    )

Вывод идентификатора запроса в логи бэкенда

Это делается путем добавления специального фильтра к обработчику логирования:

logging.yml

# только для разработки
version: 1
disable_existing_loggers: false

filters:
  # Добавляет идентификатор запроса как дополнительное поле с именем `correlation_id` к каждой записи лога.
  # Это используется в сочетании с настройкой settings.server.request_id.enabled=True
  # См. https://github.com/snok/asgi-correlation-id#configure-logging
  correlation_id:
    (): asgi_correlation_id.CorrelationIdFilter
    uuid_length: 32
    default_value: '-'

formatters:
  plain:
    (): logging.Formatter
    # Добавление correlation_id к записям лога
    fmt: '%(asctime)s.%(msecs)03d %(processName)s:%(process)d %(name)s:%(lineno)d [%(levelname)s] %(correlation_id)s %(message)s'
    datefmt: '%Y-%m-%d %H:%M:%S'

handlers:
  main:
    class: logging.StreamHandler
    formatter: plain
    filters: [correlation_id]
    stream: ext://sys.stdout

loggers:
  '':
    handlers: [main]
    level: INFO
    propagate: false
  uvicorn:
    handlers: [main]
    level: INFO
    propagate: false

Получаемые логи выглядят так:

2023-12-18 17:14:11.711 uvicorn.access:498 [INFO] 018c15e97a068ae09484f8c25e2799dd 127.0.0.1:34884 - "GET /monitoring/ping HTTP/1.1" 200

Использование заголовка X-Request-ID на клиенте

Если клиент получил заголовок X-Request-ID от бэкенда, он печатается в логах с уровнем DEBUG:

>>> import logging
>>> logging.basicConfig(level=logging.DEBUG)
>>> client.ping()
DEBUG:urllib3.connectionpool:http://localhost:8000 "GET /monitoring/ping HTTP/1.1" 200 15
DEBUG:horizon.client.base:Request ID: '018c15e97a068ae09484f8c25e2799dd'

Также, если ответ бэкенда не был успешным, Request ID добавляется к сообщению об исключении:

>>> client.get_namespace("unknown")
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http://localhost:8000/v1/namespaces/unknown
Request ID: '018c15eb80fa81a6b38c9eaa519cd322'

Заполнение заголовка X-Application-Version на бэкенде

Сервер может добавить заголовок X-Application-Version к ответам, что позволяет определить, какая версия бэкенда развернута.

Это делается через промежуточное ПО application_version, которое включено по умолчанию и может быть настроено, как описано ниже:

Bases: BaseModel

X-Application-Version Middleware Settings.

Examples

.. code-block:: bash

HORIZON__SERVER__APPLICATION_VERSION__ENABLED=True
HORIZON__SERVER__APPLICATION_VERSION__HEADER_NAME=X-Application-Version
Source code in horizon/backend/settings/server/application_version.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class ApplicationVersionSettings(BaseModel):
    """X-Application-Version Middleware Settings.

    Examples
    --------

    .. code-block:: bash

        HORIZON__SERVER__APPLICATION_VERSION__ENABLED=True
        HORIZON__SERVER__APPLICATION_VERSION__HEADER_NAME=X-Application-Version
    """

    enabled: bool = Field(default=True, description="Set to ``True`` to enable middleware")
    header_name: str = Field(
        default="X-Application-Version",
        description="Name of response header which is filled up with application version number",
    )

Использование заголовка X-Application-Version на клиенте

Если клиент получил заголовок X-Application-Version от бэкенда, он сравнивается с версией клиента.

Если версии не совпадают, показывается предупреждение:

>>> client.ping()
UserWarning: Версия клиента Horizon '0.0.9' не соответствует версии бэкенда '1.0.0'. Пожалуйста, обновите.