21 апр. 2026 г.·7 мин чтения

План семплирования ошибок для продуктов с большим объёмом событий

Составьте план семплирования ошибок, который сохраняет критические сбои, урезает шумные маршруты и согласует объём событий с серьёзностью и влиянием на клиентов.

План семплирования ошибок для продуктов с большим объёмом событий

Почему при большом объёме событий это быстро становится дорогим

При большом трафике объём ошибок редко растёт ровно. Один шумный маршрут, воркер или вебхук может выбрасывать одну и ту же ошибку тысячи раз в минуту. Тогда проблему, которую действительно нужно исправить, зарывает шум.

Сломанный путь оформления заказа, который затрагивает 200 пользователей, может выглядеть мелким рядом с задачей опроса, которая падает 50 000 раз и никому не мешает. Поэтому прямое однообразное семплирование обычно не работает. Если вы сохраняете 10% всего, вы сохраняете слишком много шума и выбрасываете слишком много редких, но серьёзных сбоев. Математика выглядит честно. Результат — нет.

Боль инженерии и боль пользователей — разные вещи. Шумная внутренняя ошибка может заполнить дашборды и разбудить людей. Ошибка с меньшим объёмом в signup, billing или checkout может затронуть меньше событий, но больше людей. Когда команды считают сырое число главным сигналом, они часто сначала чинят самый громкий маршрут и пропускают тот, что стоит денег или доверия.

Затраты обычно растут в тех же местах. Хранилище заполняется повторяющимися событиями, правила оповещений срабатывают слишком часто, а инженеры тратят время на разбор дубликатов, прежде чем найти важную проблему.

Одна глобальная стратегия кажется простой, но тратит и деньги, и внимание. Нужен жёсткий контроль над шумными маршрутами и полное хранение там, где одна ошибка критична.

Команды с очень высоким объёмом быстро это понимают. Один плохой consumer вебхука или цикл повторных попыток может сгенерировать за час больше событий, чем остальное приложение за день. Если вы сохраняете всё это, вы платите за шум, будите людей по пустякам и тратите реальное инженерное время на чтение мусора. Счёт растёт первым, но большая потеря — фокус.

Начните с ошибок, которые никогда не отбрасываете

Составьте короткий список ошибок, которые вы всегда будете сохранять, даже при всплесках объёма. Если ошибка может заблокировать пользователей, помешать оплате, потерять данные или нарушить основное обещание продукта, сохраняйте каждое событие.

Процентные соотношения появятся позже. Сначала защитите пути, где одно пропущенное событие может превратиться в потерю дохода, нагрузку в поддержку или проблему доверия, которую трудно восстановить.

Большинству команд стоит хранить полные данные для сбоев при входе, сбросе пароля и управлении сессиями, а также для checkout, billing, возвратов, изменений подписок и любых операций записи, которые могут потерять или повредить данные клиентов. Изменения аккаунта с риском безопасности или прав доступа тоже должны быть в той же группе.

Применяйте то же правило к новым ошибкам. Когда ошибка появляется впервые, сохраняйте её на 100%, пока кто-то не проверит. Новые проблемы часто выглядят маленькими из‑за неверной группировки, неправильной метки маршрута или пока только один клиент её не встретил. Если вы начнёте семплировать слишком рано, вы потеряете лучшие доказательства.

Относитесь к внезапным всплескам так же. Если один крэш затрагивает много пользователей в коротком окне, остановите семплирование для этой группы и держите полный поток, пока команда не разберётся с причиной. Количество может ввести в заблуждение, но резкий всплеск по одному и тому же маршруту, релизу или типу устройства обычно указывает на реальное влияние на клиентов.

Запишите эти правила «не отбрасывать» прежде чем настраивать проценты. Держите их короткими и конкретными. Назовите маршруты, типы задач и группы ошибок, которые остаются с полным захватом, и укажите, кто может это изменить.

Одностраничный набор правил лучше догадок. Он помогает при скачках трафика, когда новый коллега правит настройки наблюдаемости или когда финансы спрашивают, почему некоторые события остаются несэмплированными. Ответ простой: упущенные сбои стоят дороже, чем их хранение.

Группируйте события по маршруту и типу задач

Если все ошибки попадают в одну корзину, самые загруженные части продукта зарывают сбои, которые вам обходятся дороже всего. Начните с формы трафика, а не с сырых чисел.

Разбейте события на группы, которые соответствуют тому, как продукт реально работает. Веб-страницы, API-эндпоинты, фоновые работники и планировщик падают по разным причинам и создают разный уровень шума.

Простая дробление достаточно в начале:

  • web routes для пользовательских страниц
  • API routes для вызовов фронтенда и приложений
  • workers для очередей, импорта и асинхронных задач
  • scheduled jobs для cron‑задач, чисток и отчётов

Это быстро окупается. Сломанная страница оформления заказа не должна конкурировать с шумным воркером по ресайзу изображений. Админская страница, которой пользуются пять человек в день, не нуждается в том же уровне семплирования, что поток оплаты или путь регистрации.

Очистите имена маршрутов до того, как начнёте семплировать. Если трекер сохраняет /orders/18372, /orders/18373 и /orders/18374 как разные маршруты, вы тратите объём на фрагменты URL вместо реальных паттернов. Нормализуйте их в стабильные имена вроде /orders/:id, POST /api/payments или worker.invoice_retry.

Некоторые группы заслуживают агрессивной фильтрации. Health checks часто падают волнами и мало говорят после первых нескольких срабатываний. Циклы повторных попыток могут делать то же самое, особенно когда внешний сервис замедляется и каждый воркер логирует один и тот же тайм-аут.

Держите эти шумные пути отдельно и сильно их семплируйте. Держите пути, связанные с доходом, с высоким уровнем сохранения или вообще без семплирования. Многие команды помещают админские страницы в середину: достаточно данных для отладки, но не настолько, чтобы внутренний трафик доминировал в бюджете.

Практичная настройка может сохранять 100% ошибок в checkout, login и billing, 25% ошибок админских страниц и 1% ошибок health check после первого события. Это обычно гораздо лучше, чем один глобальный процент для всего.

Добавьте правила по серьёзности, которые соответствуют реальному риску

Правила серьёзности должны опираться на вред клиенту, а не только на ярлык события. Сохраняйте полные данные для сбоев, которые лишают доступа, повреждают данные, блокируют оплату или указывают на проблему безопасности.

Это обычно означает полный захват для фатальных крашей, ошибок аутентификации, багов прав доступа, ошибок платежей и событий безопасности. Когда такое срабатывает, вы хотите иметь каждый стек‑трэйс, тег релиза, путь запроса и контекст клиента, который можно безопасно хранить.

Предупреждения требуют куда более жёсткого ограничения. Во многих продуктах предупреждения идут от ретраев, особенностей браузера, шумных SDK и ожидаемых крайних случаев. Если вы захватываете их как исключения, они зарывают ошибки, которые действительно останавливают работу.

Простой старт:

  • фатальные и события безопасности: полный захват
  • необработанные исключения в пользовательских потоках: высокий процент сохранения
  • предупреждения фоновых задач и временные клиентские предупреждения: низкий процент
  • известный валидационный шум: очень низкий процент или только подсчёт

Деплои должны временно менять правила. Если маршрут, который вчера был тихим, после релиза стал выбрасывать одно и то же исключение сотни раз, поднимите частоту захвата для этой семьи ошибок. Первые несколько событий показывают, что именно сломалось. Следующая волна показывает, насколько широко это распространено.

Это особенно важно при очень большом объёме. Крупные продакшн‑системы могут залить трекер повторными post‑deploy ошибками за минуты. Временное правило, повышающее захват для новых или быстрорастущих исключений, даёт достаточно деталей для отладки, а затем можно снова снизить уровень после исправления.

Низко‑рисковый валидационный шум должен идти в обратную сторону. Плохие купоны, пустые поля формы, просроченные приглашения или неподходящие типы файлов могут заполнить проект без пользы. Держите тонкий сэмпл, чтобы заметить изменение объёма или формы сообщения, но не сохраняйте каждую копию.

Хорошее практическое правило: если событие может стоить клиенту времени, денег, доступа или данных — сохраняйте больше. Если это в основном отражение ожидаемого некорректного ввода — сохраняйте меньше и следите за трендом.

Измеряйте влияние на клиентов, а не только счётчик

Clean Up Alert Noise
Снизьте количество пейджингов и оставьте серьёзные сбои простыми для триажа

Сырые числа событий могут ввести в заблуждение. Баг, который срабатывает 10 000 раз из‑за одного сломанного циклического запроса, выглядит огромным в дашборде, но он может затрагивать только один аккаунт. Ошибка оплаты, которая коснулась 300 разных людей по одной записи — обычно большая проблема.

Отслеживайте затронутых пользователей рядом с общим числом событий. Посчитайте уникальных пользователей, аккаунты или рабочие пространства для каждой группы ошибок за короткое окно. Это простое изменение скажет, одно ли это шумное событие или широкая проблема для пользователей.

Также важно, какое действие блокируется. Если ошибка блокирует регистрацию, оплату или работу поддержки, сохраняйте её намного больше, чем для сбоя в низко‑рисковой фоновой задаче. Семплирование должно следовать боли пользователей, а не объёму логов.

Набор небольших полей часто достаточен:

  • уникальные затронутые пользователи
  • блокировало ли это регистрацию, оплату или работу поддержки
  • к какому плану или аккаунту относится пользователь
  • повторно ли один и тот же пользователь триггерил это снова и снова

Разница между повторяющимся шумом и широким ущербом легко ускользает. Один пользователь, поражённый 10 000 раз, часто означает цикл, застрявший клиент или плохую запись. 10 000 пользователей по одному разу — это проблема релиза, зависимостей или сломанного маршрута. Эти два случая нужно семплировать совершенно по‑разному.

Платные планы могут требовать своих правил. Если ошибка затрагивает корпоративных клиентов, крупные контракты или аккаунты, за которыми команда следит, сохраняйте больше контекста и больше сэмплов даже при низком числе событий. Это даст поддержке и инженерам достаточно деталей для быстрой реакции.

Компактные команды обычно понимают это быстро. Хранение каждого повторяющегося стек‑трэйса дорого, но сбрасывать ошибки, которые блокируют checkout или лишают платную рабочую область доступа, обходится дороже. Считайте события, да. Потом спросите, кого это задело, что они пытались сделать и почувствует ли бизнес это к концу дня.

Составляйте план шаг за шагом

Начните с простой таблицы. Перечислите каждый API‑маршрут, фоновую задачу, вебхук и планировщик в одном месте. Рядом с каждым элементом укажите бизнес‑стоимость его отказа. Checkout, login, синки биллинга и задачи импорта обычно находятся вверху. Шумный воркер по ресайзу изображений — гораздо ниже.

Затем дайте каждой группе дефолтный процент семплирования. Держите первую версию простой. Можно сохранять 100% ошибок checkout, 50% ошибок настроек аккаунта, 10% тайм‑аутов поиска и 1% низко‑рискового пакетного шума. Этот первый проход обычно решает большую часть контроля затрат.

Хорошая последовательность внедрения:

  1. Группируйте события по маршруту или типу задач.
  2. Установите один дефолтный процент для каждой группы.
  3. Добавьте переопределения по серьёзности.
  4. Добавьте переопределения по влиянию на клиентов.
  5. Протестируйте правила на недавних данных.

Добавляйте серьёзность после правил по маршрутам, а не до них. Предупреждение на checkout может значить меньше, чем фатальный краш в фоновой задаче биллинга, или наоборот — если оно блокирует заказы. Решите, что в вашем продукте означает «fatal», «error» и «warning», затем переопределите дефолтную ставку, когда ярлык соответствует реальному риску. Если команда свободно использует ярлыки серьёзности, исправьте это сначала. Грязные ярлыки ведут к грязному семплированию.

Влияние на клиентов должно решать спорные случаи. Сохраняйте каждую ошибку, которая блокирует оплату, ломает вход или затрагивает много аккаунтов в коротком окне, даже если этот маршрут обычно имеет низкий процент. Если один клиент генерирует половину трафика, добавьте правило по уровню аккаунта или числу затронутых пользователей, чтобы сырая статистика не утопила реальный ущерб.

И, наконец, прогоните правила на данных за прошлую неделю перед выпуском. Проверьте, какой объём вы отбрасываете, какие серьёзные сбои остаются и не стал ли какой‑то маршрут теперь тише, чем на самом деле.

Команды с экономной инфраструктурой обычно избегают неприятных сюрпризов, делая такую сухую проверку сначала. Это занимает около часа и может сэкономить дни догадок позже. Такая дисциплина часто встречается и в командах, ориентированных на ИИ. Oleg Sotnikov, например, пишет про управление продакшн‑системами с малыми командами и жёстким контролем наблюдаемости на oleg.is.

Простой пример из продуктовой команды

Fix Your Observability Stack
Получите практическую помощь с error tracking, логированием и видимостью продакшна

Небольшая команда поддерживает подписной сервис с загрузочным потоком checkout, ежедневными задачами синхронизации и веб‑клиентом, который генерирует много безвредного браузерного шума. Объём ошибок прыгает каждый раз при релизе или промоакции, так что плоский процент семплирования быстро перестаёт работать.

Они решают это, меняя семплирование по маршруту, серьёзности и влиянию на клиентов.

Во время распродажи они сохраняют каждое исключение из checkout. Если платежи падают, суммы в корзине неверны или страница подтверждения заказа крашится, им нужны все события. Даже небольшая ошибка там может стоить реальных денег за пару часов, поэтому сохранять только 10% — плохая сделка.

Они относятся к фоновой синхронизации иначе. Тайм‑аут синка, который сам ретраится, важнее меньше, чем ошибка в checkout, особенно когда тысячи заданий выполняются каждый час. Команда держит низкий процент семплирования для таких тайм‑аутов — достаточно, чтобы заметить паттерн, но не платить за повторяющуюся одну и ту же проблему.

Релиз меняет правила снова. После появления новой версии поддержка сообщает, что несколько новых клиентов в первую неделю встретили ошибки при онбординге. Команда повышает захват для событий, связанных с новыми аккаунтами и недавними регистрациями. Это помогает ответить не на вопрос «Сколько ошибок сработало?», а на «Блокируются ли новые клиенты прямо после релиза?».

Они также чистят шумные браузерные ошибки после подтверждения причины. Например, расширение браузера внедряет плохой JavaScript и заливает трекер дубликатами исключений. После проверки, что проблема не в их приложении, они отбрасывают большую часть шума и оставляют маленький сэмпл для мониторинга. Проблема остаётся видимой, но больше не топит реальные сбои.

Результат прост. Бюджет тратят на checkout, релизы и клиентски‑видимые сбои. Повторяющиеся низко‑рисковые ошибки семплируют жёстко. А когда что‑то начинает вредить новым клиентам, они поднимают захват до того, как дашборд заполнится мусором.

Ошибки, которые скрывают важные сбои

Плоский процент кажется аккуратным, но обычно скрывает неправильные вещи. Если каждому маршруту, воркеру и фоновой задаче дать одинаковое правило, выигрывают самые громкие части продукта. Сбой входа, который блокирует доход, не должен соревноваться с чатти‑health check, который целый день падает и сам исправляется при следующей попытке.

Это один из самых распространённых способов, как план семплирования идёт не так. Команды настроены на общий объём, затем предполагают, что оставшаяся выборка всё ещё показывает правду. Чаще всего это не так. Она показывает, где шум велик, а не где боль велика.

Ретраи усугубляют это. Один плохой внешний вызов может вызвать пять ретраев в API‑маршруте, десять в воркере очереди и ещё волну из планировщика. У вас не пятнадцать отдельных проблем — у вас одна проблема, умноженная поведением кода. Если семплировать такие события без учёта ретраев, повторяющаяся ошибка может затопить более редкие краши, которые затрагивают меньше пользователей, но полностью их блокируют.

Предупреждения тоже обманывают. Продукты часто держат большую долю шумных предупреждений, потому что они выглядят безобидно, а затем выбрасывают редкие фатальные ошибки, потому что бюджет уже исчерпан. Это обратный обмен. Предупреждение, появляющееся 50 000 раз и никому не вредящее, значит меньше, чем краш, который ломает checkout у 12 платящих клиентов.

Изменения в продукте создают ещё одну слепую зону. Маршруты меняются, появляются новые задачи, а старые предположения месяцами остаются в правилах. Фоновая задача, которая была низко‑рискованной, может стать пользовательской после одного обновления продукта. Если никто не пересматривает правила, план постепенно перестаёт соответствовать продукту.

Несколько привычек помогают:

  • проверьте, не вызваны ли повторяющиеся события ретраями, петлями или дублирующими репортами
  • сравнивайте отбрасываемые события с заблокированными действиями, а не с сырым количеством
  • держите редкие краши дольше, чем частые предупреждения
  • пересматривайте правила после крупных релизов, изменений ценообразования и новых рабочих процессов

Объём важен, потому что влияет на стоимость. Важнее — влияние на клиентов. Если небольшое число пользователей не может войти, оплатить, экспортировать данные или завершить основную задачу, сохраняйте эти сбои даже когда график выглядит тихим.

Быстрая проверка перед запуском новых правил

Map Routes Before Sampling
Превратите неупорядоченные имена событий в правила, которым команда доверяет

Прежде чем внедрять новые правила семплирования, вручную просмотрите самые загруженные части продукта. Начните с топ‑10 маршрутов или типов задач по количеству событий. Вы хотите увидеть, откуда реально идёт объём, а не откуда вы предполагаете.

Эта быстрая проверка часто находит один шумный эндпоинт, который заливает систему, и несколько тихих путей, которые ломают реальные пользовательские потоки. Если поиск выбрасывает 20 000 безвредных parse‑ошибок, а checkout — 40 ошибок оплаты, второму нужно больше защиты, даже при меньшем объёме.

Ошибки first‑seen требуют особого внимания. Новые сбои легко потерять, когда семплирование агрессивно, потому что они начинаются как единичное событие. Держите first‑seen видимыми с полным захватом или близким к нему, пока не станет ясно, повторяются ли они.

Защитите маршруты, которые пользователи замечают первыми. Login, signup, billing, checkout, сброс пароля и доступ к аккаунту обычно относятся к группе «не отбрасывать». Маленький всплеск там может превратиться в тикеты в поддержку, возвраты или отток задолго до того, как общий график станет тревожным.

Один только счёт может обмануть. Сравните отсэмплированные итоги с влиянием на пользователей за то же окно времени. Задавайте простые вопросы: сколько сессий попало на ошибку, сколько пользователей было заблокировано и остановила ли ошибка задачу, которую люди пытались завершить? Фоновая задача может генерировать огромный шум. Сломанный экран входа может вредить меньшему числу событий и большему числу людей.

Ещё одна проверка важна для дежурной команды. Серьёзные сбои всё ещё должны вызывать оповещения после включения новых правил. Протестируйте этот путь намеренно. Отправьте контрольное высокосерьёзное событие по защищённым маршрутам и подтвердите, что пейджинг, дашборды и триаж всё ещё работают как команда ожидает.

Если эти проверки пройдены, правила, скорее всего, можно выкатывать. Если хоть одна проверка вызывает сомнения, приостановите выпуск и подточите фильтры, прежде чем шумные маршруты зарывают важные сбои.

Что стоит пересмотреть дальше

Правила семплирования стареют быстрее, чем многие команды ожидают. Релиз может удвоить трафик на одном маршруте, миграция может переместить ошибки в новый воркер, а изменение цен — привести к другому набору клиентов и использования. Если правила останутся заморожены, вы будете хранить дешёвый шум и пропускать сбои, которые ощущают пользователи.

Проверяйте ставки после каждого релиза, миграции и изменения ценообразования, даже если релиз кажется спокойным. Маршрут, который месяц назад было безопасно семплировать, может теперь затрагивать checkout, billing или загруженный API. Малое изменение продукта может превратить незначительную ошибку в проблему поддержки.

Держите все правила в одной короткой таблице, которую вся команда сможет прочитать за минуту. Там должно быть имя маршрута или задачи, какие ошибки остаются на 100%, какие семплируются, текущий процент и дата ревью.

Этот общий вид сокращает путаницу при инцидентах. Продукт, поддержка и инженеры видят одни и те же правила вместо догадок, почему одна проблема имеет полные детали, а другая — только несколько событий.

Отслеживайте три числа вместе: стоимость, пропущенные инциденты и время на ревью. Только стоимость подтолкнёт команды семплировать слишком агрессивно. Только время на ревью — заставит держать слишком много. Пропущенные инциденты покажут, защищает ли план всё, что важно.

Простой пример наглядно демонстрирует это. Если новый самообслуживаемый тариф приносит много мелких клиентов, ваши маршруты входа и биллинга могут ночью резко вырасти. Правильный ход — снизить семплирование на безвредных ретраях и сохранить полный захват для ошибок платёжей и блокировок аккаунтов, пока трафик не устаканится.

Если правила продолжают дрейфовать или объём трудно контролировать, полезно получить второе мнение от человека, который близко работает с продакшн‑системами. Oleg Sotnikov занимается такими вещами как Fractional CTO, фокусируясь на стоимости инфраструктуры, разработке, ориентированной на ИИ, и практической наблюдаемости для стартапов и малых бизнесов.

Часто задаваемые вопросы

Why is a flat sampling rate a bad idea?

Один глобальный процент кажется простым, но он сохраняет слишком много шума и при этом выбрасывает полезные события. Шумный воркер или вебхук могут заполнить трекер, а меньшая по объёму ошибка в checkout или login потеряется, хотя она реально вредит пользователям.

Which errors should I always keep at 100%?

Сохраняйте полную запись для всего, что блокирует вход, оплату, checkout, сброс пароля, доступ к аккаунту или операции записи, которые могут потерять или повредить данные клиента. Также держите на 100% события, связанные с безопасностью и правами доступа — одно упущенное событие там может стоить дороже, чем хранение лишнего объёма.

Should I keep first-seen errors at full capture?

Да. Держите first-seen ошибки несэмплированными, пока кто-то их не просмотрит. Новые проблемы часто выглядят маленькими: группировка криво работает, метка маршрута неправильная, или пока только один клиент с ней столкнулся.

How should I group events before I set sample rates?

Разделите события по тому, как реально работает ваш продукт: веб-маршруты, API-маршруты, фоновые воркеры и планировщик задач. Нормализуйте имена, например замените /orders/18372 на стабильный паттерн /orders/:id, чтобы URL-фрагменты не съедали бюджет.

What sample rates make sense as a starting point?

Начинайте с бизнес-риска, а не с математики. Многие команды хорошо работают с 100% для checkout, login и billing, средним уровнем для админских маршрутов и очень низким — для health checks, повторных попыток и других шумных низко-рискованных путей.

What should I do with warnings and validation noise?

Обращайтесь с предупреждениями гораздо агрессивнее, чем с исключениями. Оставьте тонкий сэмпл для странностей браузера, ретраев и ожидаемых валидационных ошибок, чтобы видеть тренды, но не давайте им заглушать ошибки, которые мешают пользователям завершать реальные задачи.

How do I measure impact instead of just counting errors?

Считайте уникальных пользователей, аккаунты или рабочие пространства рядом с общим числом событий. Петля, которая попадает в одного пользователя 10,000 раз, обычно важнее меньше, чем ошибка оплаты, которая коснулась 300 пользователей по одному разу.

What should I check before I ship new sampling rules?

Посмотрите руками самые загруженные маршруты и задачи, затем прогоните правила на недавних данных прежде чем включать их. После этого отправьте тестовое высокосерьёзное событие по защищённым путям и подтвердите, что алерты, дашборды и триаж работают как ожидается.

How often should I review my sampling plan?

Пересматривайте их после релизов, миграций, изменений ценообразования и любых обновлений продукта, которые меняют характер трафика. Если правила никогда не пересматриваются, они перестанут соответствовать продукту, и вы будете хранить дешёвый шум, пропуская клиентские сбои.

How do retries and loops distort error volume?

Ретраи, циклы и дублирующие репорты делают одну ошибку похожей на множество отдельных проблем. Если это не учесть, повторяющийся шум съедает бюджет и скрывает более редкие ошибки, которые полностью блокируют пользователей.