Node SDK настраивается целиком в коде, через init(). Вкладка Настройки → Скрипт загрузчика проекта формирует только браузерный бандл с CDN — ни один её переключатель к @buglapse/node не относится.
ts
import { init } from '@buglapse/node'
import { httpServerIntegration } from '@buglapse/node/integrations'
init({
dsn: process.env.BUGLAPSE_DSN,
environment: process.env.NODE_ENV,
release: process.env.GIT_SHA,
tracesSampleRate: 0.2,
debug: process.env.BUGLAPSE_DEBUG === 'true',
integrations: [httpServerIntegration()],
})Все опции
dsn— DSN проекта,https://{key}@{host}, из Настройки → Общие. Обязателен, если не передан свойtransport. Отсутствующий или некорректный DSN не бросает исключение: SDK один раз пишет предупреждение[Buglapse] Missing or invalid "dsn"и отбрасывает события.environment— записывается какcontexts.environmentв каждое событие (production,staging, ...). По нему работают фильтрenvironment:в поиске панели и условия на окружение в выражении фильтра.release— записывается какcontexts.releaseв каждое событие. Хорошо подходит git SHA или тег версии; с ним же сопоставляются source maps, если вы собираете или минифицируете серверный код.debug— пишет в консоль, что делает SDK ([Buglapse] ...): регистрацию интеграций, пойманные и отброшенные события, отправленные и неудачные пачки. В продакшене не включайте.integrations— интеграции для регистрации, сливаются со встроенными поname(см. ниже).tracesSampleRate— вероятность (0–1), что трейс будет отправлен. По умолчанию1. Решается один раз на трейс, так что трейс приходит со всеми спанами или не приходит вовсе. См. Трейсинг → Сэмплирование.transport— фабрика транспорта, которая заменяет пакетныйfetch-транспорт по умолчанию, напримерmakeConsoleTransportдля локальной разработки. См. Транспорты.transportOptions— настройка транспорта по умолчанию:timeout,retries,maxBatchSize,flushInterval,immediateTypes,onError. См. Транспорты.tracePropagationTargets— какие исходящие запросы получают заголовки трейса (traceparent,tracestate) отhttpTracingIntegration: строки (подстрока адреса) или RegExp. По умолчанию — все запросы; задайте, чтобы сузить. См. Распределённый трейсинг.propagateSentryTrace— отправлять тем же адресатам ещё и заголовки Sentrysentry-traceиbaggage, для сервиса на Sentry SDK, который отправляет в Buglapse. По умолчаниюfalse.sendDefaultPii— можно ли встроенным интеграциям SDK записывать персональные данные, которые они собирают автоматически. По умолчаниюfalse: в адресах, которые SDK записывает сам, сохраняются путь и имена параметров, но каждое значение параметра query/fragment становится[Filtered](/search?q=[Filtered]&page=[Filtered]) — в крошках и логах ошибок исходящих запросов,http.urlу спанов иrequest.url/request.referrerвходящего запроса.trueзаписывает всё как есть. То, что передаёт ваш код (setUser(), сообщения, атрибуты), не меняется никогда — см. Чувствительные данные.beforeSend(event, hint)— последний взгляд на каждое событие, после всех интеграций и препроцессоров: верните событие (изменённое или нет), чтобы отправить, илиnull, чтобы отбросить.hint.originalException—Error, переданный вcaptureException(). Если функция бросит исключение, событие отбрасывается.beforeBreadcrumb(breadcrumb)— вызывается для каждой хлебной крошки, автоматической или изaddBreadcrumb(), до того как она попадёт в след: верните её, чтобы оставить, илиnull, чтобы отбросить. Если функция бросит исключение, крошка отбрасывается.storage— где хранятся область запроса, активный спан и хлебные крошки.init()используетAsyncLocalStorageContextна основеAsyncLocalStorage, который разделяет параллельные запросы; менять его обычно незачем (см. Теги и контекст).resolveTraceId— даёт id трейса для нового корневого спана. По умолчанию каждый корневой спан начинает свой трейс — один на входящий запрос с HttpServerIntegration. Переопределяйте, только чтобы самим сгруппировать несколько корневых операций в один трейс.
Интеграции
UncaughtExceptionIntegration и ContextLinesIntegration включены по умолчанию. Всё остальное подключается и импортируется из @buglapse/node/integrations:
| Интеграция | Что делает |
|---|---|
httpServerIntegration | Своя область, хлебные крошки и спан http.server на каждый входящий запрос |
httpTracingIntegration | Исходящие запросы — спанами http.client |
httpErrorsIntegration | Неудачные исходящие запросы — логами ошибок |
breadcrumbsIntegration | Вызовы консоли и исходящие запросы — хлебными крошками |
nodeContextIntegration | Версия Node, ОС и имя хоста в каждом событии |
eventLoopBlockIntegration | Лог-предупреждение, когда event loop останавливается |
consoleIntegration | Вызовы console.* — событиями логов |
dedupeIntegration | Отбрасывает исключение, идентичное предыдущему |
inboundFiltersIntegration | Отбрасывает исключения по сообщению |
Управлять ими можно тремя способами:
ts
import { disable, init, use } from '@buglapse/node'
import { consoleIntegration, nodeContextIntegration } from '@buglapse/node/integrations'
// 1. Заранее, в init() — сливается со встроенными; элемент с именем встроенной заменяет её.
init({ dsn: process.env.BUGLAPSE_DSN, integrations: [nodeContextIntegration()] })
// 2. Позже, через use() — работает и до init(): вызов встаёт в очередь до него.
use(consoleIntegration())
// 3. Выключить по имени — до init() не даёт встроенной зарегистрироваться вовсе.
disable('uncaught-exception')use() никогда не заменяет интеграцию, уже зарегистрированную под тем же именем, — сначала вызовите disable(name). Как написать свою — на странице Своя интеграция.
Вызовы до init()
Каждый вызов до init() — captureException(), log.*(), setTag(), use(), ... — встаёт в очередь и применяется, когда появится клиент, так что модули, импортированные раньше вашего init(), всё равно могут сообщать. Исключения — span(), asyncSpan(), startInactiveSpan() и withScope(): они оборачивают код, который должен выполниться сейчас, поэтому до init() просто выполняют его без трейсинга.
Вызывайте init() один раз. Второй вызов заменяет клиент, и всё, что первый ещё держал в буфере, теряется.
Несколько клиентов
Плоский API работает с одним общим клиентом. Если один процесс должен отправлять в несколько проектов (например, многоарендный воркер), создайте дополнительные клиенты через createClient():
ts
import { AsyncLocalStorageContext, createClient } from '@buglapse/node'
import { nodeContextIntegration } from '@buglapse/node/integrations'
const billing = createClient({
dsn: process.env.BUGLAPSE_BILLING_DSN,
storage: new AsyncLocalStorageContext(),
integrations: [nodeContextIntegration()],
})
billing.captureException(error)
await billing.flush()Клиент, созданный так, не получает встроенных интеграций: передайте storage: new AsyncLocalStorageContext() сами (иначе параллельные операции разделят одну область) и перечислите все нужные интеграции. Не давайте второму клиенту httpServerIntegration или uncaughtExceptionIntegration, если они есть у общего, — оба подключились бы к одним и тем же событиям процесса.