Files
specs/openspec/specs/backend-platform/backend-structured-logging/spec.md
T
ksv741 8f74eba85b
Conventional commits / commits (pull_request) Successful in 10s
Specs security / security (pull_request) Successful in 21s
Specs verify / verify (pull_request) Successful in 17s
refactor: group canonical specs by domain and archive account-top-positions (#74)
- Move canonical specs into domain folders (identity, tbank, brokerage,
  portfolio, instruments, banking, frontend-platform, backend-platform).
- Remove process specs; keep still-valid unique rules in openspec/config.yaml.
- Keep project-foundation behavior as app-shell and http-api-foundation.
- Archive account-top-positions without G4 by owner decision (descoped
  review/QA recorded in process-record); sync portfolio-concentration and
  portfolio-view.
- Group AI_INDEX by domain.

Refs: WealthLedger/main#48
2026-11-02 21:47:14 +03:00

6.9 KiB
Raw Blame History

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 завершает обработку исходного запроса без ошибки, вызванной логированием