Crash, Non-Fatal and Crash-Free

Трейсер собирает необработанные ошибки приложения (CRASH) и позволяет вручную регистрировать некритические ошибки (NON_FATAL). Например, вы можете отправить в сервис ошибку, которую приложение уже обработало. За сбор отвечает initTracerError, за отправку — initTracerErrorUploader. Пример подключения приведён в быстром старте.

Срок хранения событий зависит от настроек сервера и квот проекта; значение по умолчанию в серверной конфигурации — 90 дней.

Для работы со сбоями приложения вам понадобятся следующие модули Tracer JS SDK:

МодульОписание
initTracerErrorОтвечает за сбор глобальных событий и ручную регистрацию ошибок в проекте.
initTracerErrorAsyncStackДополняет стеки ошибок цепочкой асинхронных вызовов. Для регистрации ошибок нужен initTracerError.
initTracerErrorUploaderОтвечает за отправку данных о событиях в сервис.
initTracerSessionUploaderОтвечает за отправку данных о состоянии сессий приложения в сервис.

Чтобы Tracer генерировал человекочитаемые стектрейсы, необходимо загрузить отладочную информацию (source maps). Подробнее о минификации JS-приложений читайте на странице Минификация (Source Maps)

Инициализация модулей

Для начала установите SDK – введите в терминале команду:

npm install @apptracer/sdk --save

Проинициализировать SDK в проекте можно двумя способами:

  • вариант 1: сконфигурировать необходимые модули отдельно друг от друга;
  • вариант 2: проинициализировать единый объект SDK

В вашем app.js:

import { initTracerError, initTracerErrorUploader, initTracerSessionUploader } from '@apptracer/sdk'; initTracerError(); const config = { versionName: BUILD_VERSION_NAME, // строка с версией приложения из вашей сборки appToken: 'appToken из настроек в Трейсере', }; initTracerErrorUploader(config); initTracerSessionUploader(config);

Конфигурация initTracerError

По умолчанию модуль собирает необработанные ошибки: error и unhandledrejection в браузере, uncaughtException и unhandledRejection в Node.js. Для отправки нужен initTracerErrorUploader. Настройки ниже позволяют изменить сбор; особенности завершения Node.js-процесса описаны в быстром старте.

Подключайте модуль один раз. Настройки задаются при первом вызове initTracerError(), а повторный вызов вызывает исключение. Для доступа к уже подключённому модулю используйте getTracerModules().error.

ПараметрТипОписание
disableUnhandledErrorsListenersbooleanОтключает автоматическую подписку на необработанные ошибки, на случай, если хочется обрабатывать их самостоятельно.
filterError(error: Error, errorInfo: ITracerErrorInfo) => boolean | voidВозврат false исключает ошибку из сбора, в том числе при ручной регистрации.
handleOtherErrorDataTypebooleanВключает сбор необработанных значений, не являющихся Error; по умолчанию выключен. Значение сохраняется как cause созданной ошибки. Для ручного error(value) этот флаг не требуется.
stackTraceLimitnumberЗадаёт Error.stackTraceLimit — число кадров стека в средах, которые поддерживают эту настройку. По умолчанию SDK устанавливает 50.
stringifyErrorDataObjectbooleanВключает JSON-представление объекта cause в causeSimpleValue (при отправке — до 100 символов, в filterError и хуках — до этого сокращения); по умолчанию используется обозначение типа объекта. Не ограничивает общий JSON-контекст или сообщение ошибки.
maxContextValueLengthnumberМаксимальная длина каждого строкового значения контекста, включая отметку сокращения. По умолчанию 750. Правила и серверные ограничения.
maxContextArrayLengthnumberМаксимальное число сохраняемых элементов каждого массива в контексте. По умолчанию 100. Правила и серверные ограничения.
maxContextDepthnumberЧисло раскрываемых уровней контекста, включая корень. По умолчанию 5; более глубокие объекты и массивы заменяются маркерами. Правила.

Подробнее о копировании контекста и его лимитах — в разделе JSON-контекст.

filterError

Пример функции фильтрации ошибок на основе message зарегистрированной ошибки:

import { initTracerError } from '@apptracer/sdk'; initTracerError({ filterError: (error) => { if (error.message.indexOf('ignore error with this text') !== -1) { return false; } } }); // ошибка не будет отправлена в Трейсер throw new Error('ignore error with this text');

Ручная регистрация ошибок

Вы можете зарегистрировать обработанную ошибку в Tracer в качестве NON_FATAL – для этого воспользуйтесь методом error() у экземпляра, возвращённого initTracerError():

ПараметрТипОписание
valueunknownОбъект ошибки, которую вы хотите зарегистрировать. Если она не является инстансом Error, будет создана ошибка, а переданное значение будет использовано как cause.
data?ITracerErrorDataДополнительная информация об ошибке (подробнее см. ниже)
import { initTracerError } from '@apptracer/sdk'; const tracerError = initTracerError(); try { JSON.parse('wrong json data'); } catch (error) { tracerError.error(error); }

Для глобальной ошибки браузера без стектрейса доступная информация дополнительно берётся из ErrorEvent


Дополнительная информация об ошибке

ITracerErrorInfo

Стандартный набор информации об ошибке содержит следующие данные:

ПараметрТип
errorError
errorEventTypeErrorEventType
timestampnumber
logstring | undefined
errorStackstring
causeSimpleValue?string
propertiesITracerErrorProperties

В ITracerErrorInfo также входят дополнительные данные из таблицы ниже. Поле context содержит JSON-копию контекста с типом TracerJsonObject. В браузере состояние видимости страницы доступно в properties.documentVisibilityState.

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

ПараметрТипОписание
contextTracerErrorContextКонтекст конкретного экземпляра события: вложенные объекты, массивы, строки, числа, boolean и null. Поля верхнего уровня переопределяют общий контекст. Подробнее.
keysRecord<string, string | number | boolean>Ключи только для этой ошибки. Дополняют общие ключи и заменяют их значения при совпадении имён. Ограничения сервера.
userIdstring | number ID пользователя (только для данной ошибки).
issueKeystringСпециальный ключ, влияющий на группировку событий в общем списке (подробнее см. ниже).
crashIdSourcestringСтрока, которая используется вместо стектрейса как основа группировки. Сервер дополнительно учитывает компонент и важность ошибки. Не включайте динамические данные, например userId: иначе одна ошибка разделится на группы по пользователям.
componentstringИспользуйте этот параметр, если ваше приложение состоит из множества самостоятельных компонентов (распространённая ситуация для web). Сбои, зафиксированные внутри компонента, будут выделены в отдельную группу. Версии приложения также будут сгруппированы по компоненту.
severitystringУровень логирования (серьезности) ошибки, используется для классификации ошибок.

Доступные значения:
fatal (влияет на crash-free),
error,
warning,
notice,
debug
versionNamestringПереопределяет значение из настроек аплоадера. Может быть полезно в сочетании с component.
versionCodenumberПереопределяет значение из настроек аплоадера. Может быть полезно в сочетании с component.

Дополнительные флаги

Эти данные добавляются в информацию об ошибке автоматически:

ФлагТипОписание
asyncModuleEnabled?booleanУказывает на то, был ли включен модуль асинхронных стектрейсов при регистрации ошибки
asyncModuleDataAdded?booleantrue, если с ошибкой или операцией её регистрации связан async-контекст. Не гарантирует сохранение всех кадров после применения лимитов. Без контекста поле отсутствует.
asyncMaxChainDepth?numberФактическая максимальная глубина async-цепочки: от 1 до 256, по умолчанию 32.
asyncCollapseRepeats?stringФактический режим повторов: never, onError или onRegistration.
asyncChainTruncated?booleanЧасть ранних переходов потеряна из-за ограничения глубины цепочки.
asyncStackTruncated?booleanТекст сокращён из-за общего бюджета стека.
modifiedByPlugins?stringИнформация об ошибках, модифицированных с помощью плагина. Подробнее здесь

asyncMaxChainDepth и asyncCollapseRepeats показывают фактические значения настроек maxChainDepth и collapseRepeats модуля initTracerErrorAsyncStack(). Подробнее о режимах и их влиянии на стек и затраты SDK — в разделе «Глубина async-цепочки и повторы».

issueKey

По умолчанию сбои группируются по стектрейсу. Чтобы объединить NON_FATAL одного вида независимо от места регистрации, передайте одинаковый issueKey. Он также отображается в названии события.

Аудитория и crash-free

crash-free показывает процент пользователей, у которых за выбранный период не было сбоев. Для расчёта этой метрики подключите initTracerSessionUploader.

Рассчитывается метрика как (1 - (Пользователи со сбоем / Все пользователи)) * 100%. При этом важно понимать, что использование приложения на разных устройствах одного пользователя или переустановка приложения на текущем устройстве будут обозначены как самостоятельные единицы при расчётах. Отчёты о полученных Трейсером сбоях и графики по событиям можно найти в разделе «Сбои».

initTracerSessionUploader автоматически создаёт сессию и отправляет её активность. Отдельно вызывать initTracerSession() не нужно. Для учёта сбоев и crash-free подключите initTracerError, а для отправки самих ошибок — initTracerErrorUploader.

В браузере сессия сохраняется, пока веб-приложение остаётся в памяти вкладки. В Node.js она заканчивается вместе с процессом. Смена пользователя, пауза SDK и возвращение в видимую вкладку не меняют UUID сессии.

SDK периодически отправляет сведения об активности сессии, в том числе после сбоя.

В скрытой вкладке отправка сведений об активности приостанавливается, а сбор и отправка ошибок продолжаются. При возвращении во вкладку отправка активности возобновляется.

Параметры initTracerSession():

ПараметрТипОписание
sampledbooleanПризнак выборки сессии. Пока не поддерживается.
import { initTracerError, initTracerErrorUploader, initTracerSessionUploader } from '@apptracer/sdk'; initTracerError(); initTracerErrorUploader({ versionName: BUILD_VERSION_NAME, // строка с версией приложения из вашей сборки appToken: 'appToken', // appToken из настроек проекта в Tracer }); initTracerSessionUploader({ versionName: BUILD_VERSION_NAME, // строка с версией приложения из вашей сборки appToken: 'appToken из настроек в Трейсере' });

Подробнее о параметрах конфигурации Uploader-а ищите в Быстрый старт

Ограничение отправки сервером

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

Асинхронные стектрейсы

Модуль доступен в основной браузерной версии SDK.

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

Пауза и удаление модуля

Для временной паузы используйте disableTracerModules(), а для продолжения работы — enableTracerModules().

Если сбор асинхронных стеков больше не нужен, вызовите destroy() у объекта, возвращённого initTracerErrorAsyncStack(). Для повторного подключения после удаления снова вызовите initTracerErrorAsyncStack(); enableTracerModules() удалённый модуль не восстанавливает.

Глубина async-цепочки и повторы

По умолчанию сохраняются 32 ближайших асинхронных перехода, а соседние одинаковые переходы объединяются при подготовке ошибки:

initTracerErrorAsyncStack({ maxChainDepth: 32, collapseRepeats: 'onError' });

maxChainDepth задаёт число сохраняемых async-переходов — от 1 до 256. Большая глубина даёт больше контекста, но увеличивает расход памяти и время обработки ошибки. При превышении лимита отбрасывается начало цепочки и добавляется отметка [Async chain truncated].

collapseRepeats определяет, когда объединять соседние одинаковые переходы:

ЗначениеЧто даётВлияние на работу
neverКаждый переход виден отдельно. Повторы занимают место, поэтому начало цепочки теряется раньше.Нет затрат на сравнение повторов, но итоговый стек может быть длиннее.
onError — по умолчаниюПовторы объединяются при подготовке ошибки.Меньше работы до ошибки; сравнение выполняется при её обработке. Уже отброшенные переходы не восстанавливаются.
onRegistrationПовторы объединяются сразу и занимают одну запись. В длинной повторяющейся цепочке сохраняется больше раннего контекста.Больше работы при обычном выполнении. Полезно для углублённой диагностики выбранной группы пользователей.

Защитный лимит текста

При подключённом initTracerErrorAsyncStack весь отправляемый стек ограничен 256000 единицами UTF-16. При превышении SDK сокращает стек. Отдельной настройки этого лимита нет.

Флаг asyncChainTruncated означает сокращение цепочки по глубине, а asyncStackTruncated — сокращение текста стека.

Разные настройки для групп пользователей

Настройки задаются при инициализации. Например, приложение может выбирать более подробный сбор для отдельных пользователей:

// appConfig — пример конфигурации вашего приложения, не часть SDK. const detailed = appConfig.detailedAsyncDiagnostics; initTracerErrorAsyncStack({ maxChainDepth: detailed ? 256 : 32, collapseRepeats: detailed ? 'onRegistration' : 'onError' });

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

При параллельном выполнении нативных async/await-обработчиков контекст после await может теряться или смешиваться, особенно при ручном вызове error(). Настройки глубины и объединения повторов на это ограничение не влияют.

В средах без WeakRef обработчики addEventListener(..., { signal }) продолжают работать, но регистрируются без сбора async-контекста и его переноса OpenTelemetry. Для остальных подписок WeakRef не требуется. Если связь с трассировкой нужна такому обработчику, привяжите её явно через context.bind(...).

Конфигурация initTracerErrorAsyncStack

ПараметрТипОписание
maxChainDepthnumberМаксимальная глубина сохраняемой async-цепочки: целое число от 1 до 256, по умолчанию 32. Влияние настройки.
collapseRepeats'never' | 'onError' | 'onRegistration'Когда объединять соседние одинаковые переходы: никогда, при ошибке или при регистрации. По умолчанию onError. Различия между режимами описаны выше.
patchResizeObserverbooleanВключает сбор контекста ResizeObserver; по умолчанию выключен.
disableStackCleanupbooleanОтключает удаление частей стектрейса из дополнительных функций-обёрток, необходимых для работы модуля.
disablePatchPromisebooleanЗначение true отключает соответствующий патч; по умолчанию патч включён (флаг false).
disablePatchQueueMicrotaskbooleanЗначение true отключает соответствующий патч; по умолчанию патч включён (флаг false).
disablePatchSetTimeoutbooleanЗначение true отключает соответствующий патч; по умолчанию патч включён (флаг false).
disablePatchSetIntervalbooleanЗначение true отключает соответствующий патч; по умолчанию патч включён (флаг false).
disablePatchEventTargetbooleanЗначение true отключает соответствующий патч; по умолчанию патч включён (флаг false).

Недопустимые значения maxChainDepth и collapseRepeats вызывают исключение при инициализации. Изменение исходного объекта конфигурации после инициализации не меняет настройки модуля.

Пример асинхронного стектрейса в небольшом демо: https://apptracer.ru/async-demo/

В вашем app.js:

import { initTracerError, initTracerErrorUploader, initTracerErrorAsyncStack } from '@apptracer/sdk'; initTracerErrorAsyncStack(); initTracerError(); initTracerErrorUploader({ versionName: BUILD_VERSION_NAME, // строка с версией приложения из вашей сборки appToken: 'appToken из настроек в Трейсере' }); (function main() { setTimeout(function onTime() { Promise.resolve('wrong_json').then(data => { JSON.parse(data); }); }); })();

В результате получаем ошибку с полной информацией о цепочке вызовов:

SyntaxError: Unexpected token 'w', "wrong_json" is not valid JSON at JSON.parse (<anonymous>) at https://apptracer.ru/async-demo/index.js:1:9543 (Promise.then onFulfilled) at https://apptracer.ru/async-demo/index.js:1:9529 (setTimeout) at HTMLButtonElement.main (https://apptracer.ru/async-demo/index.js:1:9476)