adb logcat: как снять логи Android и прочитать их
Как снять логи Android через adb logcat, сохранить их в файл, отфильтровать по уровню, тегу и PID и найти причину вылета по stack trace.
Logcat представляет собой системный журнал Android, то есть кольцевой буфер, в который пишут сама система, системные сервисы и приложения. Чтобы снять логи, выполните adb logcat на компьютере с подключённым телефоном (отладка по USB включена) или откройте просмотрщик logcat в инструменте вроде ADBKit. Главный навык состоит в том, чтобы не читать всё подряд, а отфильтровать несколько строк, которые объясняют проблему.
Как снять логи и сохранить в файл
Чаще всего лог нужно отдать разработчику или в поддержку:
adb devices
adb logcat -c
# воспроизведите проблему на телефоне
adb logcat -d -v threadtime > log.txt-c очищает буфер, чтобы в лог попало только нужное, а -d выгружает накопленное и завершает команду. Если нужно писать лог непрерывно, уберите -d и остановите запись сочетанием Ctrl+C:
adb logcat -v threadtime > logcat.txtЕсли adb devices пустой или показывает unauthorized, сначала исправьте подключение: adb unauthorized и другие ошибки.
Что записывает logcat
У каждой записи есть уровень, тег и сообщение. Тег обычно называет компонент, который написал строку (ActivityManager, OkHttp или имя вашего класса). Записи хранятся в нескольких буферах, среди них main (логи приложений), system, crash и events. Буферы кольцевые: старые строки исчезают по мере появления новых.
Уровни от наименее к наиболее важному:
| Буква | Уровень | Для чего |
|---|---|---|
| V | Verbose | Очень подробная трассировка |
| D | Debug | Отладочная информация разработчика |
| I | Info | Обычные события жизненного цикла |
| W | Warning | Что-то неожиданное, но не критичное |
| E | Error | Операция завершилась ошибкой |
| F | Fatal | Состояние, после которого процесс не выживет |
Как читать одну строку
В формате -v time строка выглядит так:
10-06 14:03:21.456 E/AndroidRuntime( 1234): FATAL EXCEPTION: mainСлева направо: дата и время, уровень (E), тег (AndroidRuntime), ID процесса в скобках (1234), затем сообщение. Формат по умолчанию в современных Android, threadtime, показывает рядом с PID ещё и ID потока:
10-06 14:03:21.456 1234 1250 E AndroidRuntime: FATAL EXCEPTION: mainPID оказывается самым полезным полем, когда шумят сразу несколько приложений: один ID процесса выделяет один запущенный экземпляр вашего приложения.
Основные команды adb logcat
adb logcat # живой поток
adb logcat -v time # формат со временем, как выше
adb logcat *:W # предупреждения и выше, все теги
adb logcat -s MyTag # только тег MyTag
adb logcat --pid=1234 # только один процесс
adb logcat -d # выгрузить буфер и выйти
adb logcat -c # очистить буфер
adb logcat -b crash # буфер вылетовPID приложения узнаётся командой adb shell pidof com.example.app. Параметры можно комбинировать, например adb logcat -v time --pid=1234 *:W.
Совет: очистите буфер через
-cперед тем, как воспроизвести ошибку. Получится короткий чистый лог, который легко читать.
Как читать stack trace
Когда приложение вылетает, logcat выводит Java- или Kotlin-трассировку под строкой E/AndroidRuntime:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.app, PID: 1234
java.lang.RuntimeException: Unable to start activity
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ...
at com.example.app.MainActivity.onCreate(MainActivity.java:42)Читайте в таком порядке:
- Первая строка после
FATAL EXCEPTIONназывает исключение, которое всплыло наружу. - Найдите последний
Caused by:. Обычно это и есть первопричина. - Найдите первую строку
atиз вашего пакета (здесьMainActivity.java:42). С неё и начинайте смотреть код.
Кадры из android.* или java.* показывают, как фреймворк дошёл до этого места, но сам баг в них бывает редко. Больше приёмов в статье как найти stack trace вылета в logcat.
Logcat в ADBKit
В рабочем пространстве ADBKit есть панель Logcat, которая работает в браузере на Chromium (Chrome, Edge), без установки и без аккаунта. Она получает записи порциями, по умолчанию каждые 2 секунды, интервал можно поменять на 1, 2, 5 или 10 секунд. Это не непрерывный поток.
Что умеет панель:
- Фильтр по уровню от verbose до fatal.
- Поиск с учётом регистра и регулярными выражениями.
- Включение и исключение тегов, например
Foo, -NoisyпокажетFooи скроетNoisy. - Фильтр по PID и по установленному приложению, чтобы смотреть одно приложение, не выясняя его PID.
- Свёрнутые stack trace: строки трассировки прячутся под строкой ошибки и раскрываются по клику.
- Контекстное меню по правому клику, чтобы скрыть или показать записи по тегу, процессу или шаблону сообщения.
- Пауза, очистка, копирование и экспорт в текстовый файл.
Логи идут только между браузером и телефоном, сервера, который бы их принимал, у ADBKit нет.
Logcat на самом телефоне
Если компьютера нет, logcat можно запустить прямо на телефоне. Приложение ADB Kit для Android подключается к adb телефона через «Отладку по Wi-Fi» (Android 11+, без root), и во вкладке Shell работают те же команды с правами adb shell: logcat -d *:E или logcat --pid=$(pidof com.example.app), а поток останавливается через Ctrl+C. См. ADB на Android без компьютера.
Практический порядок отладки
- Очистите лог (
adb logcat -cили Clear в панели). - Поставьте уровень Warning или Error и выберите своё приложение в фильтре или по PID.
- Один раз воспроизведите проблему.
- Поставьте вывод на паузу. Найдите первую ошибку рядом с моментом сбоя: последующие ошибки часто лишь следствия.
- Откройте stack trace, дойдите до последнего
Caused by:, затем до строки вашего кода. - Если причина неясна, понизьте уровень до Info или Debug и расширьте окно времени вокруг этой строки.
- Экспортируйте или скопируйте нужные строки для баг-репорта.
Вылеты, которые убивают процесс, иногда оставляют подробности в буфере crash, поэтому после сбоя стоит попробовать adb logcat -b crash -d. Другие команды собраны в шпаргалке по командам adb.
Внимание: в логах бывают имена аккаунтов, токены и другие личные данные. Просмотрите файл, прежде чем прикладывать его к публичному баг-репорту.