Трейсер предоставляет набор инструментов, которые позволяют отслеживать сбои типа CRASH (необработанные ошибки приложения) и вручную регистрировать некритические ошибки – NON_FATAL (даже если ошибка была обратана, имеет смысл зафиксировать её в сервисе). За сбор данных о событиях отвечает модуль initTracerError, а для отправки событий необходимо сконфигурировать initTracerErrorUploader (подробнее в Быстрый старт).
ВАЖНО! Трейсер хранит данные о событиях за последние 90 дней.
Для работы со сбоями приложения вам понадобятся следующие модули Tracer JS SDK:
| Модуль | Описание |
|---|---|
initTracerError | Отвечает за сбор глобальных событий и ручную регистрацию ошибок в проекте. |
initTracerErrorAsyncStack | Отвечает за сбор и регистрацию ошибок в асинхронном коде проекта. |
initTracerErrorUploader | Отвечает за отправку данных о событиях в сервис. |
initTracerSessionUploader | Отвечает за отправку данных о состоянии сессий приложения в сервис. |
Чтобы Tracer генерировал человекочитаемые стектрейсы, необходимо загрузить отладочную информацию (source maps). Подробнее о минификации JS-приложений читайте на странице Минификация (Source Maps)
Для начала установите SDK – введите в терминале команду:
npm install @apptracer/sdk --save
Следите за актуальностью используемой версии, самая свежая – 2.6.3.
Проинициализировать SDK в проекте можно двумя способами:
В вашем app.js:
import { initTracerError, initTracerErrorUploader, initTracerSessionUploader } from '@apptracer/sdk'; initTracerError({ // ваши параметры }); const config = { versionName: BUILD_VERSION_NAME, versionCode: BUILD_VERSION_CODE, appToken: 'appToken из настроек в Трейсере', environment: 'prod', }; initTracerErrorUploader(config); initTracerSessionUploader(config);
При базовой конфигурации Трейсер позволяет регистрировать и отправлять в сервис глобальные события – ошибки типов error и unhandledrejection. Однако можно сконфигурировать модуль более гибко под ваши предпочтения.
ВАЖНО! Конфигурация применится только при первой инициализации модуля. При повторных вызовах инстант не вернется. Для получения инстанса лучше пользоваться getTracerModules (подробнее).
| Параметр | Тип | Описание |
|---|---|---|
disableUnhandledErrorsListeners | boolean | Отключает автоматическую подписку на необработанные ошибки, на случай, если хочется обрабатывать их самостоятельно. |
filterError | (error: unknown, errorInfo: ITracerErrorInfo) => boolean / void | Функция для фильтрации необработанных ошибок, если это необходимо. При результате false ошибка не будет отправлена. |
handleOtherErrorDataType | boolean | Позволяет обрабатывать события error и unhandledrejection, не являющиеся инстансами Error. Все данные будут сохранены в виде строки длиной до 50 символов. |
restrictOtherErrorListeners | boolean | Отменяет событие для других обработчиков, если не хочется делиться ошибками с кем-от еще. Не работает, если disableUnhandledErrorsListeners = true. |
stackTraceLimit | number | Переопределяет значение Error.stackTraceLimit – количество фреймов, которое включается стектрейс при регистрации ошибки |
stringifyErrorDataObject | boolean | Включает/выключает преобразовывание данных объекта в строку до 50 символов. Будьте осторожны с привытными данными. |
Пример функции фильтрации ошибок на основне 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 – для этого воспользуйтесь методом initTracerError.error():
| Параметр | Тип | Описание |
|---|---|---|
error? | unknown | Объект ошибки, которую вы хотите зарегистрировать. Если она не является инстансом Error, будет создана кастомная ошибка, у дополнительная информация будет использована в качетсве cause. |
data? | ITracerErrorData | Дополнительная информация об ошибке (подробнее см. ниже) |
import { initTracerError } from '@apptracer/sdk'; const tracerError = initTracerError(); try { JSON.parse('wrong json data'); } catch (e: any) { const error = e instanceof Error ? e : new Error('unknown error'); tracerError.error( error, // можно передать дополнительные данные, если необходимо { keys: { url: location.href }, userId: currentUserId, module: 'production', issueKey: 'special-request', // подробнее см. ниже } ); }
В случае, если для ошибки нет стектрейса, информация по ней будет дополнительно браться из ErrorEvent
Стандартный набор информации об ошибке содержит следующие данные:
| Параметр | Тип |
|---|---|
error | Error |
errorEventType | ErrorEventType |
timestamp | number |
log | string | undefined |
errorStack? | string |
causeSimpleValue? | string |
documentVisibilityState? | string |
properties | ITracerErrorProperties |
Вместе с ошибкой вы можете передать дополнительную информацию о ней в качестве параметров:
| Параметр | Тип | Описание |
|---|---|---|
keys | Object.<string, string | number | boolean> | key/value значения (только для данной ошибки). |
userId | string | number | ID пользователя (только для данной ошибки). |
issueKey | string | Специальный ключ, влияющий на группировку событий в общем списке (подробнее см. ниже). |
crashIdSource | string | Строка, которая будет использована вместо стектрейса для формирования группы ошибок, т.е. ошибки с одинаковым значением crashIdSource попадут в одну группу. Рекомендуем не использовать динамические данные (например, userId – иначе одна и та же ошибка попадет в разные группы для разных пользователей). |
component | string | Используйте этот параметр, если ваше приложение состоит из множества самостоятельных компонентов (распространённая ситуация для web). Сбои, зафиксированные внутри компонента, будут выделены в отдельную группу. Версии приложения также будут сгруппированы по компоненту. |
severity | string | Уровень логирования (серьезности) ошибки, используется для классификации ошибок. Доступные значения: fatal (влияет на crash-free),error,warning,notice,debug |
versionName | string | Переопределяет значение из настроек аплоадера. Может быть полезно в сочетании с component. |
versionCode | number | Переопределяет значение из настроек аплоадера. Может быть полезно в сочетании с component. |
Эти данные добавляются в информацию об ошибке автоматически:
| Флаг | Тип | Описание |
|---|---|---|
asyncModuleEnabled? | boolean | Указывает на то, был ли включен модуль асинхронных стектрейсов при регистрации ошибки |
asyncModuleDataAdded? | boolean | Указывает на то, был ли дополнен стектрейс асинхронными данными. Благодаря этому вы сможете найти ошибки с такими данными, даже если async-модуль включен не на всех пользователей. |
modifiedByPlugins? | string | Информация об ошибках, модифицированныз с помощью плагина. Подробнее здесь |
По умолчанию все сбои группируются по общим частям стектрейса, но в случае NON_FATAL может возникнуть необходимость выделить ошибку среди других аналогичных. Дело в том, что не всегда стектрейс и место, в котором залогировали ошибку, связаны между собой. Существует способ повлиять на эту группировку и собрать все NON_FATAL одного вида ошибки в одну группу при помощи специального ключа issueKey. Этот параметр также будет отображаться в названии события.
Преимущество issueKey в том, что не только вы сможете легко найти NON_FATAL, относящиеся к конкретной проблеме, но и другие разработчики смогут л егко найти по ключу точку логирования этой ошибки (и удалить при необходимости) и отследить его в вашем issue-трекере.
Для того, чтобы оценить надежность приложения и его способность сохранять работоспособность в течение продолжительного периода, Трейсер позволяет рассчитывать crash-free – процент пользователей, у которых не возникало сбоев в работе приложения за выбранный период. Отвечает за фичу модуль initTracerSessionUploader.
Рассчитывается метрика как (1 - (Пользователи со сбоем / Все пользователи)) * 100%. При этом важно понимать, что использование приложения на разных устройствах одного пользователя или переустановка приложения на текущем устройстве будут обозначены как самостоятельные единицы при расчётах. Отчёты о полученных Трейсером сбоях и графики по событиям можно найти в разделе «Сбои».
Перед использованием initTracerSessionUploader убедитесь, что в вашем проекте инициализирован initTracerError, иначе использование модуля будет бесполезно.
import { initTracerError, initTracerSessionUploader } from '@apptracer/sdk'; initTracerError(); initTracerSessionUploader({ versionName: BUILD_VERSION_NAME, versionCode: BUILD_VERSION_CODE, appToken: 'appToken из настроек в Трейсере' });
Подробнее о параметрах конфигурации Uploder-a ищите в Быстрый старт
Часто возникают ситуации, когда ошибки случаются в асинхронном коде (например, во время обработки результатов запроса). В таких ошибках обычно очень мало информации, а потому непонятно, как мы к ней пришли (какой код вызвал данный запрос?). Модуль initTracerErrorAsyncStack позволяет дополнить стектрейс имеющейся ошибки.
| Параметр | Тип | Описание |
|---|---|---|
disableStackCleanup | boolean | Отключает удаление частей стектрейса из дополнительных функций-обёрток, необходимых для работы модуля. |
disableCheckNativeFunctions | boolean | Отключает проверку нативных функций. По умолчанию они не включены в асинхронный модуль, поэтому в редких случаях, в зависимости от вашего проекта, отключение проверки нативных функций может немного понизить влияние на производительность. |
disablePatchPromise | boolean | Отключает патчинг. По умолчанию включено. |
disablePatchQueueMicrotask | boolean | Отключает патчинг. По умолчанию включено. |
disablePatchSetTimeout | boolean | Отключает патчинг. По умолчанию включено. |
disablePatchSetInterval | boolean | Отключает патчинг. По умолчанию включено. |
disablePatchEventTarget | boolean | Отключает патчинг. По умолчанию включено. |
Пример асинхронного стектрейса в небольшом демо: https://apptracer.ru/async-demo/
В вашем app.js:
import { initTracerError, initTracerErrorUploader, initTracerErrorAsyncStack } from '@apptracer/sdk'; initTracerErrorAsyncStack(); initTracerError(); initTracerErrorUploader({ versionName: BUILD_VERSION_NAME, versionCode: BUILD_VERSION_CODE, 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)