Можем ли мы понять журналы сбоев Android? Давайте узнаем

Можем ли мы понять журналы сбоев Android? Давайте узнаем

22 февраля 2022 г.

Ошибки журнала сбоев Android: объяснение


Сбои на Android могут очень расстраивать пользователей, настолько, что после двух сбоев обычный пользователь удалит ваше приложение. К счастью, Android Framework предоставляет несколько отличных инструментов для отладки сбоев и предоставляет несколько полезных журналов сбоев, которые разработчики могут прочитать, чтобы определить, что вызвало эту критическую проблему. В этом сообщении блога мы рассмотрим три наиболее важных журнала сбоев, используемых системой: трассировки стека исключений, трассировки ANR и захоронения NDK.


Трассировка стека исключений


Трассировка стека JVM является наиболее распространенным типом сбоя, с которым сталкиваются типичные приложения Android, поскольку большинство приложений написано либо на Kotlin, либо на Java. В языках JVM исключение создается в исключительных обстоятельствах и содержит отладочную информацию об ошибочном условии, например, трассировку стека с информацией о номере файла/строки и сообщение об ошибке.


Если в приложении не установлен пакет SDK для создания отчетов о сбоях, следующим лучшим способом получения журналов сбоев является использование adb для просмотра logcat. . Это удобный метод, если возможен физический доступ к устройству, потому что по умолчанию UncaughtExceptionHandler в приложениях Android печатает перенесите всю трассировку стека в Logcat перед завершением процесса, что означает, что аварийный выход фактически выполняется в доступном месте для разработчиков.


Трассировка ANR


ANR(приложение не отвечает) возникают, когда приложение не отвечает на действия пользователя в течение заметного периода времени. Видимый эффект этого заключается в том, что приложение «зависает» с точки зрения пользователя, что может быть очень неприятно. Общие причины включают чтение/запись диска в основном потоке и другие длительные задачи, которые не позволяют пользовательскому интерфейсу обновляться в ответ на вводимые пользователем данные.


Если приложение находится на переднем плане, примерно через 5 секунд будет показано диалоговое окно, позволяющее пользователю закрыть приложение. В этот момент на диск будет записана трассировка, включающая детали ANR, из которой можно извлечь ценную информацию для отладки. Опять же, для этого требуется физический доступ к устройству, если у вас не установлен пакет SDK для отчетов о сбоях, который поддерживает обнаружение ANR.


Надгробие


Журналы сбоев Tombstone записываются, когда в приложении Android происходит собственный сбой в коде C/C++. Платформа Android записывает трассировку всех запущенных потоков во время сбоя в /data/tombstones вместе с дополнительной информацией для отладки, такой как информация о памяти и открытых файлах. Надгробия ближе всего к металлу с точки зрения информации, поскольку они будут записывать такие детали, как необработанные адреса памяти, и поэтому их может быть немного сложнее понять, если вы не знакомы с отладкой собственного кода. Опять же, для чтения надгробий требуется физический доступ к корневому устройству.


Как получить журналы сбоев с устройства Android


В качестве предварительного условия для всех этих шагов у вас должна быть [установлена ​​Android Studio] (https://developer.android.com/studio) и добавлены [инструменты командной строки] (https://developer.android.com/studio/ командной строки) на ваш путь. Эти локальные методы используют инструмент adb. У вас также должно быть подключено устройство или эмулятор, на котором включены [параметры разработчика] (https://developer.android.com/studio/debug/dev-options).


:::Информация


Примечание. Если вам удобно использовать Device File Explorer в Android Studio напрямую, вы можете открывать файлы устройства непосредственно оттуда, а не используя adb pull.


Трассировка стека исключений


По умолчанию трассировки стека исключений распечатываются в инструмент Logcat на устройствах Android. Журналы сбоев можно получить, выполнив следующие действия:


  1. Запустите следующую команду

```javascript


adb logcat AndroidRuntime: E *: S


  1. Вызовите сбой на устройстве. Трассировка стека будет отображаться в терминале как новый текст.

  1. Сохраните вывод терминала в файл по вашему выбору для последующего просмотра.

Если недавно на устройстве произошел сбой, вы можете пропустить шаг 2. Это связано с тем, что Logcat сохраняет буфер последних журналов, который должен включать исключение. Однако это зависит от времени, поэтому, если вы ищете сбой, произошедший день назад, эта информация может быть потеряна навсегда, если вы не используете инструмент для создания отчетов о сбоях, такой как Bugsnag.


Трассировка ANR


  1. Активируйте ANR на устройстве.

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

```javascript


adb pull /data/anr/traces.txt <назначение>


  1. Проверьте информацию в журнале сбоев ANR, открыв сохраненный файл

Кроме того, вы можете просмотреть сводную информацию ANR, выполнив следующую команду


```javascript


adb logcat ActivityManager: E *: S


Надгробие


  1. Выполните рутирование вашего устройства или эмулятор, чтобы получить доступ к каталогу захоронения. (Будьте осторожны при рутировании устройств, так как этот шаг потенциально может привести к поломке вашего телефона)

  1. Запустите собственный сбой на устройстве.

  1. Выполните следующую команду, чтобы определить, какие журналы сбоев-захоронений присутствуют на устройстве.

```javascript


adb ls /данные/надгробия


  1. Выполните следующую команду, заменив место назначения файлом по вашему выбору. tombstone_01 показано здесь в качестве примера имени файла, которое было бы получено на предыдущем шаге.

```javascript


adb pull /data/tombstones/tombstone_01 <назначение>


  1. Проверьте информацию в журнале сбоев Tombstone, открыв сохраненный файл.

Анализ данных журнала сбоев Android


Трассировка стека исключений


Чтение трассировки стека JVM поначалу может быть пугающим, но если разбить ее на составные части, задача станет довольно простой. Давайте рассмотрим это шаг за шагом со следующим RuntimeException, которое было сгенерировано в примере приложения:


```javascript


2019-08-27 16:10:28.303 10773-10773/com.bugsnag.android.example E/AndroidRuntime: НЕИСПРАВНОЕ ИСКЛЮЧЕНИЕ: основной


Процесс: com.bugsnag.android.example, PID: 10773


java.lang.RuntimeException: фатальный сбой


в com.example.foo.CrashyClass.sendMessage(CrashyClass.java:10)


в com.example.foo.CrashyClass.crash(CrashyClass.java:6)


в com.bugsnag.android.example.ExampleActivity.crashUnhandled(ExampleActivity.kt:55)


в com.bugsnag.android.example.ExampleActivity$onCreate$1.invoke(ExampleActivity.kt:33)


в com.bugsnag.android.example.ExampleActivity$onCreate$1.invoke(ExampleActivity.kt:14)


на com.bugsnag.android.example.ExampleActivity$sam$android_view_View_OnClickListener$0.onClick(ExampleActivity.kt)


в android.view.View.performClick(View.java:5637)


в android.view.View$PerformClick.run(View.java:22429)


в android.os.Handler.handleCallback(Handler.java:751)


в android.os.Handler.dispatchMessage(Handler.java:95)


на android.os.Looper.loop(Looper.java:154)


в android.app.ActivityThread.main(ActivityThread.java:6119)


в java.lang.reflect.Method.invoke (собственный метод)


на com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)


на com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)


Первое место, с которого нужно начать, находится в верхней части нашего журнала сбоев. Здесь мы видим идентификатор процесса, который система присвоила исполняющемуся приложению, а также имя пакета, что может быть полезно при сопоставлении с другой информацией, полученной с помощью logcat. В нашем примере приложения имя пакета — «com.bugsnag.android.example»:


```javascript


Процесс: com.bugsnag.android.example, PID: 10773


Следующая полезная часть информации — это класс исключений. В Java/Kotlin все исключения и ошибки являются классами, которые расширяют Throwable или один из подклассов Throwable, и каждый класс исключений может иметь другую семантическую имея в виду. Например, разработчик может создать исключение IllegalStateException, если программа вошла в неожиданное состояние, или исключение IllegalArgumentException, если пользователь попытался сохранить null в качестве своего имени. В нашем случае мы создали RuntimeException, полное имя класса которого показано ниже:


```javascript


java.lang.RuntimeException: фатальный сбой


Сообщение об ошибке также печатается в журнале сбоев, что может быть очень полезно для предоставления дополнительной отладочной информации. В нашем случае мы только что предоставили текст «Фатальный сбой», но мы могли бы также передать значения наших переменных во время сбоя, если нам нужна дополнительная информация для отладки.


Следующим в нашем крашлоге является пикантная часть информации — трассировка стека потока, в котором произошло исключение. Глядя на верхний кадр стека, мы обычно можем точно определить, откуда была выдана ошибка, а кадры под ним позволяют наблюдать, в каком состоянии была программа во время сбоя. Верхний стекфрейм выглядит следующим образом:




```javascript


com.example.foo.CrashyClass.sendMessage(CrashyClass.java:10)


Сразу видно, что это содержит очень полезную информацию. Нам дан класс «com.example.foo.CrashyClass», так что мы можем открыть исходный файл и поискать там ошибку. Нам также дается имя метода «sendMessage» и номер строки сбоя, 10, поэтому мы можем точно указать в нашем источнике, откуда было выдано исключение.


Понимание журнала сбоев с этого момента и далее — это случай чтения кадров стека ниже, которые расположены в том порядке, в котором методы были первоначально вызваны. Рассмотрим пример ниже:


```javascript


в com.example.foo.CrashyClass.sendMessage(CrashyClass.java:10)


в com.example.foo.CrashyClass.crash(CrashyClass.java:6)


в com.bugsnag.android.example.ExampleActivity.crashUnhandled(ExampleActivity.kt:55)


Начиная сверху, мы можем сказать, что «sendMessage» был вызван «crash», который, в свою очередь, был вызван методом «crashUnhandled», который, по-видимому, и является причиной нашего сбоя. Конечно, полная трассировка стека исключений была несколько сложнее и также включала вызовы методов в среде Android, но основной принцип остался прежним.


Важно отметить, что в рабочей среде приложения часто [запутываются] (https://developer.android.com/studio/build/shrink-code) с помощью таких инструментов, как Proguard, что может означать отсутствие исходных символов и трассировка стека становится непонятной. К счастью, большинство служб отчетов о сбоях предоставляют подключаемые модули, которые автоматически загружают файл сопоставления, содержащий информацию, необходимую для обозначения отчетов о сбоях в рабочих приложениях.


Трассировка ANR


Трассировки ANR содержат очень большой объем информации. Поскольку ANR потенциально может быть вызвано тем, что несколько приложений борются за ограниченное количество ресурсов, полный журнал сбоев содержит трассировки стека для нескольких разных процессов. Эта полная информация может быть очень полезна для отладки, когда ничего не помогает, но в большинстве случаев сводной информации ANR, напечатанной в Logcat, достаточно для отладки ошибки. Рассмотрим следующее:


```javascript


2019-08-27 16:12:57.301 1717-1733/system_process E/ActivityManager: ANR в com.bugsnag.android.example (com.bugsnag.android.example/.ExampleActivity)


PID: 10859


Причина: истекло время ожидания отправки неключевого события (ожидание отправки неключевого события, так как окно, к которому прикоснулись, не завершило обработку определенных событий ввода, которые были доставлены ему более 500,0 мс назад. Длина очереди ожидания: 33. Возраст заголовка очереди ожидания: 6178,1 мс.)


Нагрузка: 0,32/0,62/0,37


Использование ЦП с 323086 мс до -1 мс назад (27.08.2019 13:16:43.467 по 27.08.2019 16:12:54.131):


5,7% 1717/system_server: 2,6% пользователь + 3% ядро/ошибки: 21251 незначительный


4,7% 10392/com.bugsnag.android.example: 1,3% пользователь + 3,3% ядро/ошибки: 587 незначительных


3,9% 2375/com.google.android.gms: 2,9% пользователь + 0,9% ядро/ошибки: 71377 второстепенных 51 основных


3,1% 16/ksoftirqd/2: 0% пользователь + 3,1% ядро


2,5% 2254/com.google.android.googlequicksearchbox:search: 1,1% пользователь + 1,4% ядро/ошибки: 10193 незначительные


1,2% 10427/kworker/u8:0: 0% пользователь + 1,2% ядро


0,9% 8990/kworker/u8:2: 0% пользователь + 0,9% ядро


0,8% 1342/surfaceflinger: 0,1% пользователь + 0,7% ядро/ошибки: 35 незначительных


0,5% 1344/adbd: 0% пользователь + 0,4% ядро/ошибки: 8471 второстепенный


0,4% 1896/com.google.android.gms.persistent: 0,3% пользователь + 0% ядро/ошибки: 1106 незначительные


0,4% 1288/logd: 0,1% пользователь + 0,3% ядро/ошибки: 43 незначительные


0,3% 1806/com.android.systemui: 0,2% пользователь + 0% ядро/ошибки: 404 незначительные


0,2% 1916/com.android.phone: 0,1% пользователь + 0% ядро/ошибки: 203 незначительные


0,2% 1410/аудиосервер: 0% пользователь + 0,1% ядро/ошибки: 119 незначительные


0,1% 10429/kworker/u8:3: 0% пользователь + 0,1% ядро


0,1% 10378/com.google.android.apps.photos: 0,1% пользователь + 0% ядро/ошибки: 426 незначительных


0,1% 8/rcu_preempt: 0% пользователь + 0,1% ядро


0% 1396/jbd2/dm-0-8: 0% пользователь + 0% ядро


0% 2179/com.google.android.apps.nexuslauncher: 0% пользователь + 0% ядро/ошибки: 802 незначительные 1 основные


0% 1409/зигота: 0% пользователь + 0% ядро/ошибки: 857 незначительные


0% 3951/com.android.defcontainer: 0% пользователь + 0% ядро/ошибки: 265 незначительные


0% 10137/kworker/u9:0: 0% пользователь + 0% ядро


0% 1987/wpa_supplicant: 0% пользователь + 0% ядро


0% 10205/com.google.android.apps.docs: 0% пользователь + 0% ядро/ошибки: 50 незначительные


0% 1378/dmcrypt_write: 0% пользователь + 0% ядро


0% 2111/com.google.process.gapps: 0% пользователь + 0% ядро/ошибки: 356 незначительные


0% 3882/com.android.printspooler: 0% пользователь + 0% ядро/ошибки: 241 незначительный


0% 8829/kworker/u9:2: 0% пользователь + 0% ядро


0% 9808/kworker/u9:4: 0% пользователь + 0% ядро


0% 19/миграция/3: 0% пользователь + 0% ядро


0% 1420/rild: 0% пользователь + 0% ядро


0% 10138/kworker/u9:1: 0% пользователь + 0% ядро


0% 1339/lmkd: 0% пользователь + 0% ядро


0% 1419/netd: 0% пользователь + 0% ядро/ошибки: 59 незначительные


0% 1793/com.android.inputmethod.latin: 0% пользователь + 0% ядро/ошибки: 12 незначительные


0% 10146/com.android.gallery3d: 0% пользователь + 0% ядро/ошибки: 95 незначительные


0% 10181/android.process.acore: 0% пользователь + 0% ядро/ошибки: 52 незначительные


0% 1281/kworker/0:1H: 0% пользователь + 0% ядро


0% 10162/kworker/2:1: 0% пользователь + 0% ядро


0% 10348/com.google.android.partnersetup: 0% пользователь + 0% ядро/ошибки: 92 незначительные


0% 20/ksoftirqd/3: 0% пользователь + 0% ядро


0% 10308/android.process.media: 0% пользователь + 0% ядро/ошибки: 16 незначительных


0% 1336/healthd: 0% пользователь + 0% ядро


0% 1354/logcat: 0% пользователь + 0% ядро


0% 1709/hostapd: 0% пользователь + 0% ядро


0% 3/ksoftirqd/0: 0% пользователь + 0% ядро


0% 1341/servicemanager: 0% пользователь + 0% ядро


0% 2091/com.google.android.ext.services: 0% пользователь + 0% ядро/ошибки: 10 незначительные


0% 10475/com.google.android.apps.photos:CameraShortcut: 0% пользователь + 0% ядро/ошибки: 29 незначительные


0% 4/kworker/0:0: 0% пользователь + 0% ядро


0% 12/ksoftirqd/1: 0% пользователь + 0% ядро


0% 1422/fingerprintd: 0% пользователь + 0% ядро


0% 1591/dhcpclient: 0% пользователь + 0% ядро


0% 1706/ipv6proxy: 0% пользователь + 0% ядро


0% 1913/sdcard: 0% пользователь + 0% ядро


0% 2137/com.google.android.googlequicksearchbox:interactor: 0% пользователь + 0% ядро/ошибки: 3 незначительные


0% 687/kworker/1:1: 0% пользователь + 0% ядро


0% 1297/vold: 0% пользователь + 0% ядро/ошибки: 10 незначительные


0% 1413/installd: 0% пользователь + 0% ядро/ошибки: 35 незначительные


0% 1//init: 0% пользователь + 0% ядро


0% 11/миграция/1: 0% пользователь + 0% ядро


0% 466


Во-первых, журнал сбоев содержит информацию о том, какой процесс в системе подвергся ANR, а также дает идентификатор процесса и имя пакета, что полезно при поиске соответствующих трассировок стека в более подробной трассировке ANR:


```javascript


E/ActivityManager: ANR в com.bugsnag.android.example (com.bugsnag.android.example/.ExampleActivity)


PID: 10859


Платформа Android дает нам причину для ANR. В этом случае пользователь коснулся экрана несколько раз, и очередь отправки ждала более 6 секунд, не показывая видимого ответа на эти события касания. Это представляет собой очень плохой пользовательский опыт, который будет заметен, поскольку все приложение будет зависать с точки зрения пользователя:


```javascript


Причина: истекло время ожидания диспетчеризации ввода (ожидание отправки неключевого события, поскольку затронутое окно не завершило обработку определенных событий ввода, которые были доставлены ему более 500,0 мс назад. Длина очереди ожидания: 33. Возраст заголовка очереди ожидания: 6178,1 мс.)


Наконец, мы получили некоторую информацию о загрузке процессора. Хотя некоторые ANR имеют простые причины, такие как выполнение ввода-вывода в основном потоке, это не всегда так. Иногда ANR может возникать на низкопроизводительном устройстве из-за того, что множество ресурсоемких приложений конкурируют за ЦП, поэтому определение того, существуют ли другие приложения, использующие много ресурсов одновременно с нашим приложением, может быть очень полезным:


```javascript


Использование ЦП с 323086 мс до -1 мс назад (27.08.2019 13:16:43.467 по 27.08.2019 16:12:54.131):


5,7% 1717/system_server: 2,6% пользователь + 3% ядро/ошибки: 21251 незначительный


4,7% 10392/com.bugsnag.android.example: 1,3% пользователь + 3,3% ядро/ошибки: 587 незначительных


3,9% 2375/com.google.android.gms: 2,9% пользователь + 0,9% ядро/ошибки: 71377 второстепенных 51 основных


3,1% 16/ksoftirqd/2: 0% пользователь + 3,1% ядро


2,5% 2254/com.google.android.googlequicksearchbox:search: 1,1% пользователь + 1,4% ядро/ошибки: 10193 незначительные


Надгробие


Как и следы ANR, надгробия также содержат очень большой объем информации, которую невозможно просмотреть полностью. Мы рассмотрим усеченный пример, который показывает самую важную информацию вверху:


```javascript


АБИ: 'x86'


pid: 15300, tid: 15300, имя: android.example  >>> com.bugsnag.android.example <<<


сигнал 11 (SIGSEGV), код 2 (SEGV_ACCERR), адрес неисправности 0xb19aa650


eax b19aa650 ebx b19abfd8 ecx 00000005 edx b32a1230


эси 99365d7e эди bf9c2338


xcs 00000073 xds 0000007b xes 0000007b xfs 0000003b xss 0000007b


eip b19aa688 ebp bf9c2148 esp bf9c2140 флаги 00010296


след:


00 pc 00000688  /data/app/com.bugsnag.android.example-2/lib/x86/libentrypoint.so (crash_write_read_only+40)


01 pc 000006ca  /data/app/com.bugsnag.android.example-2/lib/x86/libentrypoint.so (Java_com_bugsnag_android_example_ExampleActivity_doCrash+42)


02 pc 003e9d3c  /data/app/com.bugsnag.android.example-2/oat/x86/base.odex (смещение 0x399000)


куча:


bf9c2100  b32dc140  [анонимно:libc_malloc]


bf9c2104 b3159f5c /system/lib/libart.so


bf9c2108 b315abb3 /system/lib/libart.so


bf9c210c b315ab82 /system/lib/libart.so


bf9c2110 b315ab69 /system/lib/libart.so


bf9c2114 b716ced4 /dev/ashmem/dalvik-LinearAlloc (удалено)


bf9c2118  b328b400  [анонимно:libc_malloc]


bf9c211c b312b721 /system/lib/libart.so (_ZN3art14JniMethodStartEPNS_6ThreadE+17)


bf9c2120 00430000


bf9c2124 00590000


bf9c2128  b328b400  [анонимно:libc_malloc]


bf9c212c  b32a1230 [анонимно:libc_malloc]


bf9c2130  b32b00c0  [анонимно:libc_malloc]


bf9c2134  b328b400 [анонимно:libc_malloc]


bf9c2138 00000043


bf9c213c b19aa66e /data/app/com.bugsnag.android.example-2/lib/x86/libentrypoint.so (crash_write_read_only+14)


00  bf9c2140  bf9c2200


bf9c2144 b19aa650 /data/app/com.bugsnag.android.example-2/lib/x86/libentrypoint.so


bf9c2148  bf9c2178


bf9c214c  b19aa6cb /data/app/com.bugsnag.android.example-2/lib/x86/libentrypoint.so (Java_com_bugsnag_android_example_ExampleActivity_doCrash+43)


01  bf9c2150  00430000


bf9c2154 00000013


bf9c2158  05980a40


bf9c215c  bf9c219c


bf9c2160 b32a1230 [анонимно:libc_malloc]


bf9c2164 0000000c


bf9c2168  bf9c21cc


bf9c216c b2bc803f /system/lib/libart.so (art_jni_dlsym_lookup_stub+15)


bf9c2170  b328b400  [анонимно:libc_malloc]


bf9c2174 0000000c


bf9c2178  bf9c21cc


bf9c217c 994aed3d /data/app/com.bugsnag.android.example-2/oat/x86/base.odex


02  bf9c2180  b32a1230  [анонимно:libc_malloc]


bf9c2184  bf9c219c


bf9c2188  05980a40


bf9c218c  00000001


bf9c2190 b716ced4 /dev/ashmem/dalvik-LinearAlloc (удалено)


bf9c2194  bf9c2c24


bf9c2198 00000001


bf9c219c 12c7b450 /dev/ashmem/dalvik-main space (удалено)


bf9c21a0 00000006


bf9c21a4 b31fbb74 /system/lib/libart.so


bf9c21a8  bf9c2238


bf9c21ac  b2f3a0a4  /system/lib/libart.so (_ZNK3art7OatFile8OatClass19GetOatMethodOffsetsEj+100)


bf9c21b0  bf9c21cc


bf9c21b4 99365d7e /data/app/com.bugsnag.android.example-2/oat/x86/base.odex


bf9c21b8  bf9c2338


bf9c21bc  b2bc9263  /system/lib/libart.so (art_quick_invoke_stub+339)


Разбивая его, мы получаем важную информацию журнала сбоев в верхней части, такую ​​​​как имя пакета и идентификатор процесса. Крайне важно, поскольку это собственная ошибка, на которую может повлиять архитектура ЦП, захоронение также содержит ABI устройства, в данном случае это x86, поскольку сбой был вызван на эмуляторе:


```javascript


АБИ: 'x86'


pid: 15300, tid: 15300, имя: android.example  >>> com.bugsnag.android.example <<<


Нам предоставляется информация о собственной ошибке, которая в данном случае возникла из-за возбуждения сигнала SIGSEGV. Он содержит адрес, по которому возникла ошибка, а также инструкции по сборке:


```javascript


сигнал 11 (SIGSEGV), код 2 (SEGV_ACCERR), адрес неисправности 0xb19aa650


eax b19aa650 ebx b19abfd8 ecx 00000005 edx b32a1230


эси 99365d7e эди bf9c2338


xcs 00000073 xds 0000007b xes 0000007b xfs 0000003b xss 0000007b


eip b19aa688 ebp bf9c2148 esp bf9c2140 флаги 00010296


Остальная часть трассировки содержит символы, которые выполнялись во время сбоя, которые могут быть обозначены с помощью отладочной информации в общих объектных файлах вашего приложения — функция, которую Bugsnag реализует автоматически с интеграцией плагина Gradle.


Следующие шаги


Хотя получение журналов сбоев вашего устройства Android вручную может быть очень полезным в определенных ситуациях, можно автоматизировать сбор журналов сбоев, установив SDK для отчетов о сбоях, например Bugsnag Android SDK. /android/) в вашем приложении. Пакеты SDK для отчетов о сбоях автоматически обнаруживают сбои JVM, сбои NDK и ошибки ANR и автоматически доставляют диагностический отчет об ошибке на веб-панель управления.


Автоматический сбор журналов сбоев имеет несколько преимуществ. У вас не всегда может быть доступ к устройству, особенно если произошел сбой на устройстве конечного пользователя, или если вы нанимаете стороннюю фирму по обеспечению качества, у них могут не быть установлены необходимые инструменты для получения журналов сбоев вручную из тестовое устройство. Пакеты SDK для отчетов о сбоях предлагают автоматические отчеты об ошибках из вашего рабочего приложения, чтобы вы могли сразу получить представление о том, сколько пользователей затронуто ошибкой, и определить, как ее исправить с помощью диагностической информации.


Большим преимуществом SDK для отчетов о сбоях является то, что к отчету об ошибке можно прикрепить пользовательские метаданные. Журналы сбоев на устройстве ограничены объемом информации, которую может собрать платформа Android, но таких ограничений нет, когда речь идет о сторонних инструментах. Например, Bugsnag автоматически собирает навигационные цепочки на Android события жизненного цикла и общие системные трансляции, которые могут помочь отследить сложные ошибки, связанные с неожиданным состоянием в событии жизненного цикла.


Службы отчетов о сбоях также предлагают мощные функции поиска и сегментации. Возможно, ошибка возникает только в определенных версиях ОС, или критическая ошибка с покупками в приложении влияет на коэффициент конверсии ваших платных клиентов. Добавляя пользовательские метаданные в отчеты об ошибках, можно сегментировать и искать важные ошибки, чтобы вы могли определить приоритеты того, что приносит пользу вашему бизнесу, вместо того, чтобы тратить время на ручное сопоставление журналов сбоев с десятков устройств самостоятельно.



Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE