6.9 KiB
backend-structured-logging Specification
Purpose
Определяет безопасные структурированные backend-логи, позволяющие связать HTTP-запрос, его ответ и вызовы T-Bank при диагностике инцидентов.
Requirements
Requirement: Backend публикует единообразные структурированные события
Backend SHALL записывать lifecycle-, HTTP-, authentication-, domain- и T-Bank-события в stdout как Pino JSON-записи с time, level, message и безопасным context. Записи MUST поддерживать уровни debug, info, warn и error; уровень вывода MUST настраиваться валидируемой конфигурацией LOG_LEVEL с production-значением по умолчанию info.
Scenario: Приложение успешно запускается
- WHEN backend завершает запуск
- THEN stdout содержит info JSON-событие запуска с безопасными service и environment
Scenario: Выбран уровень debug
- WHEN backend запущен с допустимым
LOG_LEVEL=debug - THEN stdout содержит debug-события наряду с событиями более высоких уровней
Scenario: Указан недопустимый уровень логирования
- WHEN backend запущен с недопустимым значением
LOG_LEVEL - THEN запуск завершается ошибкой валидации конфигурации
Requirement: HTTP-запросы имеют сквозной идентификатор
Backend SHALL создавать server-generated request ID для каждого HTTP-запроса, включать его в связанные с запросом log-события и возвращать его в response header X-Request-ID. CORS MUST разрешать browser-клиенту прочитать этот header. Входящий request ID MAY быть записан отдельным недоверенным полем, но MUST NOT заменять server-generated request ID и MUST NOT влиять на авторизацию или обработку запроса.
Scenario: Клиент получает идентификатор запроса
- WHEN browser-клиент получает HTTP-ответ backend
- THEN ответ содержит
X-Request-ID, доступный через CORS, и этот же ID присутствует в HTTP log-событии
Scenario: Клиент передаёт собственный идентификатор
- WHEN HTTP-запрос содержит client-provided request ID
- THEN backend использует другой server-generated request ID для обработки и логирования запроса
Requirement: Backend фиксирует итог каждого HTTP-запроса
Backend SHALL записывать ровно одно completion-событие для каждого HTTP-запроса с request ID, HTTP method, route template, status и duration. Completion-событие MUST иметь level info для обычных ответов, warn для authentication failures и status 429, error для status 5xx. События с ошибкой MUST включать стабильный public error code; error-события для status 5xx MUST включать stack trace.
Scenario: Запрос завершается успешно
- WHEN backend возвращает ответ со status 2xx
- THEN stdout содержит одно info completion-событие с route template без query string и длительностью обработки
Scenario: T-Bank недоступен во время запроса
- WHEN backend возвращает клиенту status 503 с public error code
TBANK_UNAVAILABLE - THEN stdout содержит одно error completion-событие с этим code, request ID и stack trace
Scenario: Запрос не проходит аутентификацию
- WHEN backend возвращает status 401 или 403
- THEN stdout содержит одно warn completion-событие без отдельного дублирующего события ошибки
Requirement: События T-Bank позволяют диагностировать интеграцию
Backend SHALL записывать события вызовов T-Bank с request ID, именем операции и duration, когда вызов выполняется в контексте HTTP-запроса. Успешный вызов MUST иметь level debug, повтор вызова MUST иметь level warn, а окончательный сбой MUST иметь level error и содержать gRPC code и число попыток.
Scenario: Вызов T-Bank успешен с первой попытки
- WHEN вызов T-Bank завершается успешно без повтора
- THEN stdout содержит debug-событие операции с её duration и request ID
Scenario: Вызов T-Bank повторяется и затем завершается ошибкой
- WHEN вызов T-Bank исчерпывает разрешённые попытки
- THEN stdout содержит warn-событие повтора и error-событие окончательного сбоя с gRPC code и числом попыток
Requirement: Логи не раскрывают секретные и чувствительные данные
Backend MUST NOT записывать в логи token, cookie, JWT, пароль, полный HTTP header, HTTP body, email, IP-адрес, финансовые значения или payload T-Bank. В production-логах MAY присутствовать только внутренние user ID и brokerage account ID, если они известны при формировании события. Ошибка формирования или вывода log-события MUST NOT менять HTTP-ответ или результат доменной операции.
Scenario: Запрос содержит секретные данные
- WHEN HTTP-запрос содержит authentication cookie, JWT или тело с паролем
- THEN связанные log-события не содержат эти значения
Scenario: Событие не сериализуется
- WHEN backend не может сериализовать поле log-события
- THEN backend завершает обработку исходного запроса без ошибки, вызванной логированием