📎 Чего не дают логи, метрики и трейсы — 28 июня 2026 г. в 07:00:04.807
📎 Чего не дают логи, метрики и трейсы Идея «три столпа наблюдаемости» звучит убедительно. Соберите логи, метрики и трейсы, отправьте в одну платформу, и поймёте систему. На практике у команды есть все три, а баг в проде она всё равно не находит. Ниже главные мысли статьи о том, почему так выходит, с примерами на Go. 🖇 Данные есть, понимания нет Три столпа дают сигналы, но не объяснение. На инциденте вы коррелируете то, что собрали заранее, часто в спешке, и этого набора не хватает под конкретный сбой. 🖇 Высокая кардинальность бьёт первой Как только вам нужен разрез по user_id, арендатору или связке эндпоинт плюс регион, метрики ломаются. Так делать не стоит, потому что число рядов взрывается: // Плохо. user_id и tenant дают почти неограниченное число комбинаций. httpRequests := prometheus.NewCounterVec( prometheus.CounterOpts{Name: "http_requests_total"}, []string{"endpoint", "region", "user_id", "tenant"}, ) httpRequests.WithLabelValues(endpoint, region, userID, tenant).Inc() Безопаснее держать в метках только ограниченный набор значений, а детали уносить в трейс или лог: // Лучше. В метках только то, у чего мало возможных значений. httpRequests := prometheus.NewCounterVec( prometheus.CounterOpts{Name: "http_requests_total"}, []string{"endpoint", "region", "status"}, ) httpRequests.WithLabelValues(endpoint, region, status).Inc() 🖇 Инструментация видит только ожидаемое Вы измеряете то, что предусмотрели заранее. Новый тип сбоя не попадает ни в один график, и в этот момент вы слепы. 🖇 Худшие баги живут между сервисами Два микросервиса по своим метрикам здоровы, задержки в трейсах нормальные, логи чистые. А вместе они выдают неверный ответ. Проблема в связи между ними, и ни одна отдельная метрика её не ловит. 🖇 Зелёные метрики не значат правильный результат Три столпа описывают инфраструктуру, а не бизнес. Сервис может держать отличную задержку и нулевые ошибки, при этом считать цену неверно. Поэтому полезно мерить сам бизнес-результат, а не только технику: // Считаем не задержку, а расхождение цены. Это и есть семантическая наблюдаемость. span.SetAttributes( attribute.String("order.id ", order.ID ), attribute.Int64("order.expected_cents", expected), attribute.Int64("order.charged_cents", charged), ) if charged != expected { priceMismatchTotal.Inc () } 🖇 Лучшее улучшение делается после инцидента Самый сильный приём звучит скучно. После разбора спросите, какой информации не хватило, и добавьте её. Часто это пара полей в структурном логе через slog, которых раньше не было: // После разбора добавили request_id и tenant. Без них инцидент искали вслепую. slog.Error("payment declined", "request_id", reqID, "tenant", tenant, "provider", provider, "code", declineCode, ) Эффект накапливается, и через год полтора команда отлаживает прод заметно быстрее. Вывод простой. Три столпа это стартовая точка, а не финал. Современные системы грязнее и сильнее завязаны на деньги, поэтому и наблюдаемость нужна с высокой кардинальностью, ориентированная на события и привязанная к бизнес-результату. Наша рассылка даёт максимум за минимум.

