Шум можно отсечь в двух местах:
- на сервере — правила в панели, применяются сразу и без деплоя. Отфильтрованные события не хранятся и не расходуют квоту;
- в SDK — событие вообще не уходит из приложения. Так экономится и трафик, и квота.
Начните с серверных фильтров: в большинстве проектов их хватает.
Встроенные фильтры сервера
Откройте Настройки → Фильтры и включите нужные переключатели:
| Фильтр | Что отбрасывает |
|---|---|
| Фильтровать известных краулеров | События от поисковых ботов и краулеров, по user agent посетителя |
| Фильтровать ошибки гидратации | Ошибки рассинхронизации SSR во Vue и React (Hydration…, Text content does not match server-rendered HTML) |
| Фильтровать ошибки загрузки чанков | ChunkLoadError, Loading chunk … failed, Failed to fetch dynamically imported module и его аналоги в Firefox и Safari (error loading dynamically imported module, Importing a module script failed) — обычно это старая вкладка после деплоя |
Там же график «Отфильтровано событий» показывает, сколько отброшено за 30 дней.
Своё правило на сервере
Всё, что не покрывают встроенные фильтры, описывается выражением фильтра на той же странице. Каждая строка — отдельное условие: событие отбрасывается, если истинно хотя бы одно.
text
"{{event.message}}" ~ "ResizeObserver loop"
"{{event.contexts.environment}}" === "staging"
"{{event.contexts.user.ip}}" === "203.0.113.7"
"{{event.name}}" === "AbortError" && "{{event.contexts.release}}" ~ "beta"~— «содержит», без учёта регистра;===/!==— точное сравнение.- Плейсхолдер в кавычках сравнивается как строка. Под полем есть кнопки с частыми плейсхолдерами:
{{event.message}},{{event.name}},{{event.op}}, окружение, релиз, IP. - Доступны
&&,||,!и скобки. Полный синтаксис тот же, что у правила «Сбор инцидентов». - Выражение, которое не разбирается, не сохранится — панель покажет ошибку.
Выражение проверяется для событий любого типа — исключений, логов, спанов. Это функция тарифа: если поле неактивно, тариф её не включает.
Фильтры видят исходные данные
Фильтры срабатывают до вычистки чувствительных данных, поэтому пишите условия по тексту, который действительно генерирует ваш код, а не по [Filtered].
Ошибки расширений и чужих скриптов
Расширения браузера и сторонние виджеты бросают ошибки в вашей странице. Отсечь их проще всего в SDK по адресу скрипта, из которого прилетела ошибка. За это отвечает интеграция «Входящие фильтры».
Script-тег. Откройте Настройки → Скрипт загрузчика, включите Входящие фильтры и заполните списки:
- Запрещённые URL — например,
chrome-extension://,moz-extension://,safari-extension://; - Разрешённые URL — если указать свой домен (
https://app.example.com), останутся только ошибки из ваших скриптов; - Игнорировать ошибки — части текста ошибки, например
ResizeObserver loop.
Значение вида /…/флаги считается регулярным выражением, остальное — подстрокой. Изменения применятся при следующей загрузке страницы, код менять не нужно.
npm. То же самое в коде:
ts
import { init } from '@buglapse/browser'
import { inboundFiltersIntegration } from '@buglapse/browser/integrations'
init({
dsn: '{dsn}',
integrations: [
inboundFiltersIntegration({
ignoreErrors: ['Script error.', /ResizeObserver loop/],
denyUrls: [/^chrome-extension:\/\//, /^moz-extension:\/\//],
allowUrls: ['https://app.example.com'],
}),
],
})Если передать ignoreErrors, список по умолчанию (['Script error.']) заменится — добавьте 'Script error.' сами. С заполненным allowUrls отбрасываются и ошибки без адреса в стеке.
В Node.js полезен только ignoreErrors — например, для ECONNRESET или socket hang up. Подробнее: InboundFiltersIntegration для Node.
«Script error.»
Так браузер показывает ошибку из скрипта с другого домена, если тот загружен без CORS: ни текста, ни стека. Исправить можно двумя способами:
- Отдавать скрипт с заголовком
Access-Control-Allow-Originи подключать сcrossorigin="anonymous"— тогда ошибка придёт целиком. - Если скрипт чужой и повлиять на него нельзя — отбросить такие ошибки: включите «Входящие фильтры» (в них
Script error.игнорируется по умолчанию) или добавьте строку"{{event.message}}" ~ "Script error"в выражение фильтра.
Любая логика в коде: beforeSend
Когда правило зависит от данных, которых нет у сервера, — проверьте событие перед отправкой. beforeSend вызывается последним для каждого события: верните null, чтобы его отбросить.
ts
init({
dsn: '{dsn}',
beforeSend(event) {
// Ошибки отменённых запросов — не баг
if (event.type === 'exception' && event.payload.name === 'AbortError') return null
// Логи уровня debug в продакшене не нужны
if (event.type === 'log' && event.payload.level === 'debug') return null
return event
},
})Для «хлебных крошек» есть такой же beforeBreadcrumb. Все опции — в справочнике: Browser, Node.
Слишком много событий: сэмплирование
- Трейсы. В Настройки → Фильтры → Сэмплирование задайте Долю трейсов, например
10%. Решение принимается на трейс целиком, отброшенные спаны не тарифицируются. В SDK то же самое делает опцияtracesSampleRate. - Всплески. Защита от всплесков включена по умолчанию: если тип событий резко вырос, сервер начинает его сэмплировать, а не отрезать. Первые события каждой новой ошибки сохраняются всегда. Подробнее — в Квотах и лимитах.
Игнорировать или отфильтровать?
Кнопка Игнорировать на странице инцидента только убирает его из списка и отключает алерты. События по-прежнему сохраняются и расходуют квоту. Если ошибка — точно шум, отфильтруйте её одним из способов выше.