Перейти к основному содержимому

Observability

Зачем нужно

Документ задаёт единые правила логов, аудита, метрик и трассировки для всех 7 доменов. Один формат — одна корреляция между сервисами.

Стек

СигналТехнология
Логиpino (JSON) → Loki
МетрикиOpenTelemetry → Prometheus
ТрассировкиOpenTelemetry → Tempo
ErrorsSentry
AlertingGrafana Alerting + Sentry alerts
UIGrafana

Корреляция

  • X-Request-Id — генерируется на gateway или клиенте, прокидывается через все сервисы и события.
  • traceparent (W3C Trace Context) — для трассировки.
  • X-User-Id (внутренний заголовок между сервисами) — никогда не полагаться на него для авторизации, только для логов.

Один request от клиента до фоновой задачи имеет один requestId.

Логи

Формат

JSON-строки, поля:

time, level, service, env, requestId, traceId, spanId, userId,
actorContext, message, code, durationMs, ctx

level: trace|debug|info|warn|error|fatal.

Что логируется

  • входящий HTTP-запрос (метод, путь, status, durationMs);
  • исходящий HTTP-запрос/ответ (без тел);
  • доменные события (входящие, исходящие);
  • бизнес-операции с changeset;
  • ошибки и стек.

PII в логах

  • Email, телефон, имя — маскируются: j***@example.com, +79*******12, И. И..
  • Пароли, токены, коды — никогда.
  • Реализация: общий redaction-конфиг pino в packages/observability.

Retention

УровеньСрок
trace/debug7 дней
info/warn30 дней
error/fatal90 дней
audit7 лет (см. ниже)

Audit

Audit отделён от application logs. Каждое чувствительное действие пишется в audit:

  • actor_user_id, actor_context, service_client;
  • permission_used;
  • target_entity, target_id;
  • operation;
  • before/after (для критичных полей);
  • request_id, message_id;
  • created_at.

Audit хранится в БД сервиса домена (таблица audit_log) + опционально дублируется в shared audit storage. Retention — 7 лет, неизменяем (append-only, без UPDATE/DELETE).

Что обязано писаться в audit:

  • любое изменение прав доступа;
  • любая финансовая операция;
  • ручные корректировки;
  • изменение публикаций;
  • сброс пароля и смена методов входа;
  • изменение reference-данных;
  • административные действия.

Metrics

Формат имени

<domain>_<resource>_<action>_<unit>

Примеры:

  • lms_enrollment_created_total
  • crm_payment_succeeded_total
  • identity_login_failed_total
  • competitions_submission_processed_seconds_bucket
  • platform_event_processed_total
  • platform_http_request_duration_seconds

Обязательные labels

  • service, env, version;
  • endpoint (для HTTP);
  • message_type (для шины);
  • status/code (success/failure).

Что измеряется

  • HTTP: requests total, durations, errors;
  • DB: queries total, durations, errors;
  • Events: published, consumed, processing duration, retries, DLQ count;
  • Business: domain-specific (записи, активации, входы, ошибки checking).

SLO/SLA

Базовые цели:

  • p95 HTTP latency: < 300 ms для пользовательских CRUD;
  • p99 background job latency: < 5 minutes;
  • error rate: < 0.5% за 5 минут;
  • бюджет ошибок: 0.1% (99.9% доступности);

Конкретные значения по сервису — в domains/<name>/security.md или в SLO-документах SRE.

Tracing

  • Трассировка включена для всех HTTP-эндпоинтов и обработчиков событий.
  • Span attributes: domain, entity, operation, userId, actorContext, messageId.
  • Долгие операции (>1s) — отдельный span.

Errors

  • Любая error/fatal запись логов отправляется в Sentry с тегами service, env, release, requestId, userId.
  • PII в Sentry maskируется по тем же правилам.
  • Группировка по fingerprint, алерт на регресс по version.

Health checks

  • /health/live — процесс жив (без проверки зависимостей);
  • /health/ready — готов принимать трафик (db ok, bus ok, кэш ok);
  • /health/info — версия и build.

Алерты

  • бюджет ошибок исчерпан;
  • очередь DLQ не пуста дольше 10 минут;
  • p95 latency > 1s в течение 5 минут;
  • падение health/ready;
  • audit log пишется с задержкой (если шина events падает).

Запрещено

  • Логировать пароли, токены, OTP-коды, полные refresh tokens.
  • Хранить audit в одной таблице с обычными логами.
  • Использовать metrics-имена без префикса домена/платформы.
  • Делать console.log в продакшен-коде (использовать общий logger).
  • Игнорировать requestId/traceId в логах.

Связанные документы