Tracer SDK уже предоставляет самую важную информацию о событии:
| Параметр | Какую информацию предоставляет |
|---|---|
"date" | Дата и время наступления события |
"board" | Build.BOARD – базовая плата |
"brand" | Build.BRAND – производитель/бренд устройства |
"cpuABI" | Build.SUPPORTED_ABIS – архитектура процессора, которую поддерживает устройство |
"device" | Build.DEVICE – имя промышленного образца |
"manufacturer" | Build.MANUFACTURER – изготовитель |
"model" | Build.MODEL – модель устройства |
"osVersionSdkInt" | Build.VERSION.SDK_INT – версия SDK устройства |
"osVersionRelease" | Build.VERSION.RELEASE – версия, видимая пользователю |
"cpuCount" | Runtime.getRuntime().availableProcessors() – количество доступных процессорных ядер |
"operatorName" | имя оператора (если доступно) |
"installer" | пакет установщика (если имеется) |
В некоторых случаях может быть полезным добавить к событию дополнительную информацию. Например, userId, build flavor или vendor (если сборка предназначена для предустановки). Для таких случаев Tracer предлагает ряд инструментов для получения дополнительной информации о приходящих событиях.
HasTracerSystemInfo – инструмент, который уже позволяет получить базовую информацию о событии (описали выше). Но он также дает возможность расширить список этих опций – для этого необходимо в вашем приложении:
class MyApplication : Application(), HasTracerSystemInfo { override val tracerSystemInfo: Map<String, String> get() = mapOf ( "foo" to "bar", ) }
HasTracerSystemInfo.tracerSystemInfo будет вызываться каждый раз при запуске приложения на случай ANR и при наступлении событий CRASH или NON-FATAL. Вся полученная информация о событии отображена в разделе «Данные» на странице события:

В ходе работы приложения вы можете генерировать собственные данные, которые хотели бы видеть в описании приходящих событий. Например, deviceId, статус подключения к сети или номер сборки. Tracer.setCustomProperty() позволяет дополнительно внести ваши данные в описание события.
В качестве параметра метод принимает пару «ключ/значение»:
| Параметр | Значение |
|---|---|
key: String | Имя ключа, имеет ограничение в 31 символ. Строки длиннее будут обрезаны. В случае, если параметр – пустая строка, ключ не будет записан. |
value: String? | Значение, имеет ограничение в 128 символов. Строки длиннее будут обрезаны. В случае, если параметр – пустая строка, ключ не будет записан. |
ВАЖНО! На данный момент количество пользовательских ключей ограничено – не более 30.
ВАЖНО! Эти данные хранятся персистентно, то есть доступны в каждой сессии приложения. Если имя ключа уже использовано, его значение будет перезаписано. Чтобы удалить уже имеющийся ключ, передайте value = NULL.
Для установки кастомных ключей в вашем приложении:
// при получении каких-то данных: Tracer.setCustomProperty("Ваш ключ", "Ваше значение") // спустя N строчек кода: TracerCrashReport.report(NoSuchElementException("msg")) // во вкладке «Данные» в описании события вы увидите ваши ключ и значение
Полученная информация отобразится в разделе «Данные» в блоке Other:

Вы можете завести сразу несколько кастомных сущностей, воспользовавшись Tracer.setCustomProperties():
| Параметр | Значение |
|---|---|
map: Map<String, String?> | Ваши ключи и значения. На параметры действуют те же ограничения, что и в Tracer.setCustomProperty() |
ВАЖНО! К ключам, записанным с помощью Tracer.setCustomProperties(), применяются те же правила хранения, перезаписи и удаления.
Метод является альтернативным для установки пользовательских ключей в отчёты о сбоях – он позволяет создать кастомную пару «ключ/значение». Наряду с логами ключи помогут вам понять, что предшествовало событиям.
Не путайте Tracer.setKey() с TracerCrashReport.report(e, issueKey): ключи и issueKey – это разные сущности, предназначенные для разных целей. Подробнее об использовании issueKey читайте на странице Crash и ANR.
Tracer.setKey() принимает параметры:
| Параметр | Значение |
|---|---|
key: String | Имя ключа, имеет ограничение в 31 символ. Строки длиннее будут обрезаны. В случае, если параметр – пустая строка, ключ не будет записан. |
value: String? | Значение ключа, имеет ограничение в 31 символ. Строки длиннее будут обрезаны. В случае, если параметр – пустая строка, ключ будет записан с пустым значением. |
Для установки ключей в вашем приложении:
// при получении каких-то данных: Tracer.setKey("Ваш ключ", "Значение") // спустя N строчек кода: TracerCrashReport.report(NoSuchElementException("msg")) // во вкладке «Ключи» в описании события вы увидите ваши ключи
Чтобы завести несколько ключей сразу, воспользуйтесь Tracer.setKeys(), который приним ает следующие параметры:
| Параметр | Значение |
|---|---|
map: Map<String, String?> | Ваши ключи и значения. На параметры действуют те же ограничения, что и в Tracer.setKey() |
По существующим ключам удобно осуществлять поиск среди отчётов. Полученные ключи будут отображаться в соотвутствующем разделе в описании события:

ВАЖНО! На данный момент количество пользовательских ключей ограничено – не более 15.
Метод позволяет установить id пользователя в том виде, в котором его понимает ваше приложение:
// при запуске приложения: Tracer.setUserId("Ваш userId") // спустя N строчек кода: TracerCrashReport.report(NoSuchElementException("msg")) // во вкладке «Данные» в описании события вы увидите ваш userId
Наличие userId позволяет осуществлять поиск по всем событиям приложения, пришедшим от конкретного пользователя.
Tracer.setUserId() принимает параметр:
| Параметр | Значение |
|---|---|
userId: String? | userId в том виде, в котором его понимает ваше приложение. |
ВАЖНО! Параметр хранится персистентно, то есть будет связан со всеми событиями, которые наступят после его установки, вплоть до его изменения или удаления.
Значение userId можно найти в разделе «Данные» в описании события – отсюда же возможно осуществить поиск по всем событиям этого пользователя:

Фактически вызов этого метода эквивалентен вызову Tracer.setCustomProperty("userId", "your_user_id").
Напомним, что ключи – это данные, которые позволяют уточнить обстоятельства сбоя. Например, если пользователь попал в некоторый эксперимент или в контрольную группу. В некоторых случаях может появиться необходимость установить значение ключа как можно раньше – до того, как в приложении что-то произойдет. Метод setInitialKey() позволяет проставить необходимые значения ключей еще на этапе инициализации Tracer.
| Параметр | Значение |
|---|---|
key: String | Имя ключа, имеет ограничение в 31 символ. Строки длиннее будут обрезаны. В случае, если параметр – пустая строка, ключ не будет записан. |
value: String? | Значение ключа, имеет ограничение в 31 символ. Строки длиннее будут обрезаны. В случае, если параметр – пустая строка, ключ будет записан с пустым значением. |
Для установки ключей на этапе инициализации в вашем приложении:
class MyApplication : Application(), HasTracerConfiguration { override val tracerConfiguration: List<TracerConfiguration> get() = listOf( CoreTracerConfiguration.build { setInitialKey("Ваш ключ", "Значение") }, ) }
setInitialKeys() позволяет установить сразу несколько ключей за раз, принимая в качестве параметра map-у ключей и значений:
| Параметр | Значение |
|---|---|
map: Map<String, String?> | Ваши ключи и значения. На параметры действуют те же ограничения, что и в Tracer.setInitialKey() |
Логирование позволяет отслеживать работу приложения и понять последовательность операций, которая могла привести к сбою. Например, бывает полезно узнать, что перед наступлением события пользователем нажал на какую-то кнопку. В Tracer реализовано собственное хранилище логов, которое обеспечивает безопасную запись и доступ к данным логов при наступлении определенного события.
Вы можете добавить собственные логи, воспользовавшись методом TracerCrashReport.log():
// при наступлении какого-то события: TracerCrashReport.log("button 100500 clicked") // спустя 100500 строчек: TracerCrashReport.report(NoSuchElementException("Nothing here, see logs")) // во вкладке «Логи» этого non-fatal вы увидите строчку event "button 100500 clicked"
Не путайте TracerCrashReport.log() с обычными логами вашего приложения. Полученная с помощью TracerCrashReport.log() информация собирается в циклический буфер размером 64Кб и ожидает отправки вместе с отчётом об ошибке.
Ваши логи, предшествующие наступлению события, будут приложены к описанию этого события в соответствующем разделе в описании события:

ВАЖНО! Не стоит злоупотреблять логами – они накапливаются не бесконечно. Помните об ограничении на размер буфера.