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

Шум можно отсечь в двух местах:

  • на сервере — правила в панели, применяются сразу и без деплоя. Отфильтрованные события не хранятся и не расходуют квоту;
  • в 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: ни текста, ни стека. Исправить можно двумя способами:

  1. Отдавать скрипт с заголовком Access-Control-Allow-Origin и подключать с crossorigin="anonymous" — тогда ошибка придёт целиком.
  2. Если скрипт чужой и повлиять на него нельзя — отбросить такие ошибки: включите «Входящие фильтры» (в них 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.
  • Всплески. Защита от всплесков включена по умолчанию: если тип событий резко вырос, сервер начинает его сэмплировать, а не отрезать. Первые события каждой новой ошибки сохраняются всегда. Подробнее — в Квотах и лимитах.

Игнорировать или отфильтровать? ​

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