GH GambleHub

Логування та трасування подій

Логування та трасування подій

1) Мета і рамка

Логи і трейси - фундамент спостережуваності.
Логи відповідають на «що сталося» і «з яким контекстом».
Трейси відповідають на «де і чому повільно/помилково» в розподіленому шляху запиту.

Ключові принципи:
  • Structured by default (JSON); Trace-first: кожен лог в гарячому шляху прив'язується до'trace _ id '/' span _ id'.
  • Мінімум шуму, максимум сигналу: рівні, семплінг, анти-кардинальність.
  • Безпека і приватність: маскування, редагування, розмежування доступу.
  • Версіоновані схеми логів і подій.

2) Таксономія подій

Розділяйте потоки та індекси за призначенням:

1. Технічні логи (runtime, помилки, мережеві таймаути, ретраї).

2. Бізнес-події (реєстрація, депозит, ставка, висновок, KYC-етап) - придатні для продуктової аналітики та інцидентів по «грошових» шляхах.

3. Аудит (хто/коли що змінив: конфіги, доступи, прапори, ліміти) - незмінний журнал.

4. Безпека (автентифікація, ескалації привілеїв, санкційний/РЕР-прапори).

5. Інфраструктура (K8s events, autoscaling, HPA/VPA, вузли/диск/мережа).

Для кожного потоку - окремі правила ретеншну, індексації та доступу.


3) Структурний лог (еталон JSON)

json
{
"ts": "2025-11-03T14:28:15.123Z",
"level": "ERROR",
"service": "payments-api",
"env": "prod",
"region": "eu-central-1",
"trace_id": "8a4f0c2e9b1f42d7",
"span_id": "c7d1f3a4b8b6e912",
"parent_span_id": "a1b2c3d4e5f60789",
"logger": "withdraw.handler",
"event": "psp_decline",
"msg": "PSP declined transaction",
"http": { "method": "POST", "route": "/withdraw", "status": 502, "latency_ms": 842 },
"user": { "tenant_id": "t_9f2", "user_key": "hash_0a7c", "vip_tier": 3 },
"payment": { "psp": "acme", "amount": 120.50, "currency": "EUR", "idempotency_key": "u123:wd:7845" },
"safe": true,         // пройдена проверка на секреты
"version": "1.14.2",     // версия сервиса (SemVer)
"build": "sha-1f2a3b4",
"kubernetes": { "pod": "payments-7cbdf", "node": "ip-10-0-2-41" }
}

Вимоги: плоска схема + вкладення по доменах, обов'язкові поля ('ts, level, service, env, trace_id, msg'), числові значення - числами, не рядками.


4) Рівні, кардинальність і обсяг

Рівні: 'DEBUG'( не в проді),'INFO'( бізнес-факти),'WARN'( аномалії),'ERROR'( помилки),'FATAL'( краші).
Кардинальність: уникайте довільних ключів/динамічних label'ів. Ніяких «id-в-ключі».
Семплінг логів: rate-limit повторювані повідомлення; вмикайте'DEBUG'тільки scoped і за часом (feature flag).
Ідемпотентність: логуйте'idempotency _ key', щоб придушувати дублікати подій споживачами.


5) Приватність і безпека

Маскуйте PII/секрети на агентах (Fluent Bit/Vector): карти маскування за ключами ('email','card','token','authorization').
Хешуйте'user _ key', утримуйте тільки необхідний контекст (країна, KYC-рівень, VIP-tier).
Розділіть сховища: теплі (оперативний пошук) і холодні (архів без PII/c урізаним контекстом).
Аудит - append-only, WORM-сховище, доступ тільки за принципом least privilege.


6) Трасування: стандарти та контекст

W3C Trace Context: заголовки «traceparent »/« tracestate», плюс baggage для безпечних ключів (наприклад, «tenant _ id», «region»).
Зв'язок метрик і трейсів: Exemplars - передавайте'trace _ id'в семпльовані точки гістограм (прискорює RCA).
Sampling: базовий семплінг 1-5% + динамічний «на помилках/повільному p95» до 100% для проблемних запитів.
Links: для асинхронних черг/саг зв'язуйте спани через'links', а не тільки через'parent'.


7) Збір і маршрутизація

Агенти: Fluent Bit/Vector для логів; OTLP-експорт в OpenTelemetry Collector.
Collector: центральний шлюз (batch/transform/filter/routing).

Рекомендований конвеєр:

App → (OTLP logs/traces/metrics) → OTel Collector
→ logs: redact → route(security    audit    tech    biz) → hot index / cold archive
→ traces: tail_sampling(errors    p95>threshold) → APM backend
→ metrics: Prometheus exporter (for SLO/alerts)
OTel Collector (фрагмент):
yaml processors:
batch: {}
attributes:
actions:
- key: env value: prod action: insert filter/logs:
logs:
include:
match_type: strict resource_attributes:
- key: service.name value: payments-api exporters:
otlp/traces: { endpoint: "apm:4317", tls: { insecure: true } }
loki: { endpoint: "http://loki:3100/loki/api/v1/push" }
prometheus: {}
service:
pipelines:
logs: { receivers: [otlp], processors: [attributes,batch], exporters: [loki] }
traces: { receivers: [otlp], processors: [batch], exporters: [otlp/traces] }
metrics: { receivers: [otlp], processors: [batch], exporters: [prometheus] }

8) Інструментування: приклади SDK

8. 1 Node. js (Pino + OTel)

js import pino from "pino";
import { context, trace } from "@opentelemetry/api";

const logger = pino({ level: process.env.LOG_LEVEL          "info" });

function log(info) {
const span = trace.getSpan(context.active());
const base = span? { trace_id: span.spanContext().traceId, span_id: span.spanContext().spanId }: {};
logger.info({...base,...info });
}

// пример log({ event: "deposit.created", amount: 50, currency: "EUR", user: { user_key: "hash_0a7c" } });

8. 2 Java (SLF4J + OTel)

java
MDC.put("trace_id", Span.current().getSpanContext().getTraceId());
MDC.put("span_id", Span.current().getSpanContext().getSpanId());
log.info("psp_response status={} latency_ms={}", status, latency);

8. 3 Python (structlog + OTel)

python import structlog from opentelemetry import trace log = structlog.get_logger()

def log_json(event, kwargs):
span = trace.get_current_span()
ctx = {}
if span and span.get_span_context().is_valid:
ctx = {"trace_id": span.get_span_context().trace_id, "span_id": span.get_span_context().span_id}
log.msg(event=event, ctx, kwargs)

8. 4 NGINX → трасування заголовків

nginx proxy_set_header traceparent $http_traceparent;
proxy_set_header tracestate $http_tracestate;

9) Логи як сигнал для алертів і авто-дій

Помилкові патерни ('psp _ decline','fraud _ flag') агрегуйте і корелюйте з SLO.
Алерти на pattern-rate: "5xx по/withdraw> 0. 5% за 10м", "fraud_flag spike> + 200% від базової".
Авто-дії: при логе'withdrawals _ manual _ mode = true'вмикайте kill-switch через платформу прапорів.

Приклад правила (псевдо-експресія):

rate(count_over_time({service="payments-api", level="ERROR", event="psp_decline"}[5m])) > 5

10) Ретеншн, індексація, зберігання

Гаряче: 7-14 днів (оперативне розслідування).
Тепле: 30-90 днів (тренди, RCA).
Холодне: 180-365 + (архів, аудит) - стиснення, дешеві класи, можливо без повнотекстового пошуку.
Індексація: фіксовані ключі ('service, env, level, event, trace_id, user. tenant_id'), заборона на індекс «всього підряд».
Ліміти на розмір події (наприклад, ≤ 32KB), трим/знизу: «зайве в storage - ворог MTTR».


11) Аудит і незмінюваність

Події аудиту пишіть окремим потоком з підписами/хешами, серверним часом,'who/what/when/why', посиланням на тікет.
«Хто включив прапор бонусів на 100% в DE?» - відповідь має бути в 1-2 запити.

Приклад аудиту:
json
{
"ts": "2025-11-03T14:00:00.000Z",
"actor": "alice@company",
"action": "feature_flag.update",
"target": "bonus.enable_vip",
"old": {"rollout": 10},
"new": {"rollout": 100},
"reason": "campaign_2311",
"ticket": "OPS-3481",
"trace_id": "cf12ab.."
}

12) Бізнес-події та модель даних

Бізнес-події - не «текст в логах», а контракт:
  • `event_type`, `event_id`, `occurred_at`, `actor`, `subject`, `amount`, `currency`, `status`, `idempotency_key`.
  • Використовуйте Outbox і «at-least-once» з ідемпотентними споживачами.

13) Kubernetes і pipeline логів

Sidecar/DaemonSet агенти з буфером на диск (при мережевих перервах).
Анотації подів для маршрутизації ('log. type`, `retention. tier`).
Логи K8s-контролерів збирайте окремо (кластерний індекс).

Fluent Bit (маскування, фрагмент):
ini
[FILTER]
Name     modify
Match
Remove    authorization, password, card_number

14) Анти-патерни

Рядкові логи «як доведеться», відсутність'trace _ id'.
PII/секрети в логах, дампи payload цілком.
Мільйони унікальних ключів → «підірвана» індексація.
DEBUG в проде 24/7.
Змішування аудиту, безпеки і техлогів в один індекс.
Немає ретеншн-політики і тесту відновлення з архіву.


15) Чек-лист впровадження (0-45 днів)

0-10 днів

Включити W3C Trace Context в gateway/клієнтах, прокидання заголовків.
Перекласти додаткові логи на JSON, додати'trace _ id '/' span _ id'.
Заборонити PII/секрети (маскування на агенті), затвердити список полів.

11-25 днів

Розвести потоки: tech/biz/audit/security/infra, задати ретеншн і ACL.
Увімкнути OTel Collector, зробити tail-sampling помилок/повільних запитів.
Дашборди «Log Rate/Error by route» + Jump-to-trace (Exemplars).

26-45 днів

Алерти за шаблонами подій і кореляція з SLO.
Архів/відновлення (DR-тест) для холодних логів.
Лінтер схем логів в CI, контракт для бізнес-подій.


16) Метрики зрілості

Покриття запитів'trace _ id'≥ 95%.
Частка логів JSON ≥ 99%.
Інциденти, знайдені via «jump-to-trace», вирішені <15 хв (p50).
0 випадків PII в логах (сканер витоків).
Ретеншн дотриманий по всіх потоках (аудит доводимо автоматично).


17) Додатки: міні-сніпети

W3C traceparent генерація (псевдо)

txt traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

PromQL - зв'язка логів і SLO (приклад)


high_error_logs = rate(log_events_total{service="payments-api",level="ERROR"}[5m])
5xx_rate = sum(rate(http_requests_total{service="payments-api",status=~"5.."}[5m])) / sum(rate(http_requests_total{service="payments-api"}[5m]))
alert if high_error_logs > 10 and 5xx_rate > 0.005

OpenAPI - кореляційні заголовки

yaml components:
parameters:
Traceparent:
name: traceparent in: header required: false schema: { type: string }

18) Висновок

Сильний контур логування і трасування - це угоди + дисципліна: структурні JSON-логи, єдиний'trace _ id', безпечна обробка PII, маршрутизація і ретеншн по потоках, а також тісна зв'язка з SLO, алертингом і відкатами. Зробіть перехід від «звалища текстів» до контрактів подій і трас, і діагностика прод-інцидентів стане швидкою, передбачуваною і перевіряється.

Contact

Зв’яжіться з нами

Звертайтеся з будь-яких питань або за підтримкою.Ми завжди готові допомогти!

Розпочати інтеграцію

Email — обов’язковий. Telegram або WhatsApp — за бажанням.

Ваше ім’я необов’язково
Email необов’язково
Тема необов’язково
Повідомлення необов’язково
Telegram необов’язково
@
Якщо ви вкажете Telegram — ми відповімо й там, додатково до Email.
WhatsApp необов’язково
Формат: +код країни та номер (наприклад, +380XXXXXXXXX).

Натискаючи кнопку, ви погоджуєтесь на обробку даних.