Android 系统报告收集和查看

开始

开发中接触的除了代码以外,最多的可能就是日志的。 像Android日志查看,最简单的就是这样:

adb logcat

然后系统日志就会源源不断的在控制台输出,其中包含了各种我们关心的重要的调试信息。 "图片自定义高度" height="" width="" 但是这只是一种适合开发调试的查看方式,有没有其他方法呢。

答案是肯定的,现在应用商店提供了一些自动化测试,对测试失败的设备可能会提供一些系统日志,失败的原因可能是安装失败、运行时崩溃、ANR等等,有没有想过这些日志是怎么生成的呢,对于测试小伙伴怎样在测试设备上收集系统日志呢,下面就介绍一种 android 内置的日志收集办法。

收集报告

好在 android 贴心的提供了一个工具 bugreportAndroid 的所有版本都支持通过 adb获取 bug 报告, 所以怎么使用呢: 假如发现应用出现了崩溃等异常情况时,不要慌张手机连接电脑,输入命令(这里不对 adb 环境的做介绍,后面有下载链接)

adb bugreport

静静等待报告生成并导出,结束后会有如下输出,会有一个zip包在当前路径下生成 "图片自定义高度" height="" width=""

我们可以直接解压这个zip来打开 "图片自定义高度" height="" width="" 这里只标识了一些重要的文件含义,其他的无法直接查看,需要借助到GUI工具,后面会介绍

其中最重要的就是 bugreport-meizu_18X_CN-RKQ1.210614.002-2022-12-07-11-11-54.txt,命名格式为bugrepory_<brand>_<model>_<版本号>-<yyyy-MM-dd-HH-mm-ss>.txt,里面包含了我们想要看的系统日志信息,还有电池、CPU、内存、内核日志、ANR等等信息,后面会对这些进行介绍。

这样我们的日志信息就导出来了,如果日志比较少,我们可以直接这个txt文件查阅,不过通常情况下这个文件都是比较大的,动辄几十十几M,直接查看显然不太方便,下面介绍两个GUI工具来帮助我们查看它。

查看报告

下面是Android 官方的介绍文档,里面包含了对日志文件的结构有详细的介绍,点击下面地址到官方详细介绍

阅读 bug 报告

任何类型的开发工作,bug 都在所难免,而 bug 报告对于找出和解决问题至关重要。Android 的所有版本都支持通过 adb获取 bug 报告;Android 4.2 及更高版本提供了一个开发者选项,供开发者获取 bug 报告并通过电子邮件、云端硬盘等分享报告。

Android 错误报告中包含文本 (.txt) 格式的 dumpsysdumpstatelogcat 数据,便于您轻松搜索特定内容。以下各部分详细说明了 bug 报告的组成部分,介绍了常见问题,并提供了一些实用提示和 grep 命令,用于查找与 bug 相关的日志。大多数部分中还包括 grep 命令及输出或 dumpsys 输出方面的示例。

打开 bugreport-meizu_18X_CN-RKQ1.210614.002-2022-12-07-11-11-54.txt 文件,这里了解一下它的主要内容。

Logcat 查看

system 部分专门用于记录框架方面的信息,与包含所有其他内容的 main 部分相比,该部分包含更长时间内的记录

------ SYSTEM LOG (logcat -v threadtime -v printable -v uid -d *:v) ------
--------- beginning of system
12-07 11:11:55.416  1000   621   621 E SELinux : avc:  denied  { find } for pid=30140 uid=10185 name=tethering scontext=u:r:permissioncontroller_app:s0:c185,c256,c512,c768 tcontext=u:object_r:tethering_service:s0 tclass=service_manager permissive=0
------ 0.128s was the duration of 'SYSTEM LOG' ------

事件日志

------ EVENT LOG (logcat -b events -v threadtime -v printable -v uid -d *:v) ------
--------- beginning of events
12-07 10:58:48.732  1000   621   621 I chatty  : uid=1000(system) /system/bin/servicemanager expire 13 lines
12-07 10:58:48.934  1000   621   621 I auditd  : avc:  denied  { find } for pid=30140 uid=10185 name=tethering scontext=u:r:permissioncontroller_app:s0:c185,c256,c512,c768 tcontext=u:object_r:tethering_service:s0 tclass=service_manager permissive=0
------ 0.062s was the duration of 'EVENT LOG' ------

这里只介绍这两种常用的日志部分,实际上它还包含了 stat log, radio log, last log来表示不同的日志输出,这里排查app崩溃问题可以只关心system logevent log

ANR 日志

这里介绍查找ANR堆栈信息,可能存在多组堆栈轨迹(VM TRACES JUST NOWVM TRACES AT LAST ANR),确保你找的 时间戳 和 PID 是正确的。

----- VM TRACES AT LAST ANR (/data/anr/anr_2022-11-28-16-37-21-918: 2022-11-28 16:37:30) ------

----- pid 30241 at 2022-11-28 16:37:23 -----
Cmd line: com.car300.activity
Build fingerprint: 'meizu/meizu_18X_CN/meizu18X:11/RKQ1.210614.002/1645597308:user/release-keys'
ABI: 'arm64'
Build type: optimized
Zygote loaded classes=15784 post zygote classes=8741
Dumping registered class loaders
#0 dalvik.system.PathClassLoader: [], parent #1
#1 java.lang.BootClassLoader: [], no parent
#2 dalvik.system.PathClassLoader: [/system/framework/tcmclient.jar], parent #0
#3 dalvik.system.PathClassLoader: [], parent #0
#4 dalvik.system.PathClassLoader: [/data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/base.apk:/data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/base.apk!classes9.dex:/data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/base.apk!classes5.dex:/data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/base.apk!classes2.dex:/data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/base.apk!classes6.dex:/data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/base.apk!classes3.dex:/data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/base.apk!classes4.dex:/data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/base.apk!classes7.dex], parent #1
#5 dalvik.system.PathClassLoader: [/system/framework/org.apache.http.legacy.jar], parent #1
Done dumping class loaders
Classes initialized: 4451 in 276.368ms
Intern table: 43228 strong; 536 weak
JNI: CheckJNI is on; globals=933 (plus 80 weak)
Libraries: /data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/lib/arm64/libImSDK.so /data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/lib/arm64/libche300_crypt.so /data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/lib/arm64/libcrashsdk.so /data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/lib/arm64/libijmdetect-drisk.so /data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/lib/arm64/liblocSDK8b.so /data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/lib/arm64/libmmkv.so /data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/lib/arm64/libpangleflipped.so /data/app/~~qmm-6TPCS9yh0WzbcZ3gtw==/com.car300.activity-Hd4Q6adG0VNT8xleGoOIdA==/lib/arm64/libumeng-spy.so libandroid.so libaudioeffect_jni.so libcompiler_rt.so libicu_jni.so libjavacore.so libjavacrypto.so libjnigraphics.so libmedia_jni.so libopenjdk.so libqti_performance.so librs_jni.so libsfplugin_ccodec.so libsoundpool.so libstats_jni.so libwebviewchromium_loader.so (23)
Heap: 26% free, 35MB/48MB; 584026 objects
...

suspend all histogram:	Sum: 897us 99% C.I. 0.113us-348.319us Avg: 26.382us Max: 396us
DALVIK THREADS (89):
"Signal Catcher" daemon prio=10 tid=5 Runnable
  | group="system" sCount=0 dsCount=0 flags=0 obj=0x14e402c8 self=0x71715e6200
  | sysTid=14485 nice=-20 cgrp=default sched=0/0 handle=0x6fefae6cc0
  | state=R schedstat=( 7087398 35626 13 ) utm=0 stm=0 core=4 HZ=100
  | stack=0x6fef9ef000-0x6fef9f1000 stackSize=995KB
  | held mutexes= "mutator lock"(shared held)
  native: #00 pc 00000000004a07f4  /apex/com.android.art/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+140)
  native: #01 pc 00000000005ade9c  /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool, BacktraceMap*, bool) const+376)
  native: #02 pc 00000000005cafd4  /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+924)
  native: #03 pc 00000000005c4f14  /apex/com.android.art/lib64/libart.so (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)+528)
  native: #04 pc 00000000005c40e0  /apex/com.android.art/lib64/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool)+1920)
  native: #05 pc 00000000005c3580  /apex/com.android.art/lib64/libart.so (art::ThreadList::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+776)
  native: #06 pc 000000000056f4dc  /apex/com.android.art/lib64/libart.so (art::Runtime::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+196)
  native: #07 pc 0000000000584ad4  /apex/com.android.art/lib64/libart.so (art::SignalCatcher::HandleSigQuit()+1396)
  native: #08 pc 0000000000583aa0  /apex/com.android.art/lib64/libart.so (art::SignalCatcher::Run(void*)+348)
  native: #09 pc 00000000000b009c  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+64)
  native: #10 pc 00000000000503c8  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)
  (no managed stack frames)
...

通过文本阅读始终是低效的,下面就介绍两个GUI工具

ChkBugReport

这是索尼使用 java 开发的一款专门解析 bugreport 报告的命令行工具。它是一个gradle项目,我们需要编译才可以得到命令行工具,后面会提供编译好的下载链接

git clone https://github.com/sonyxperiadev/ChkBugReport.git
cd ChkBugReport/core
./gradlew assemble

cd build/distributions
unzip ChkBugReport.zip
cd ChkBugReport

这里不对它的编译做过多介绍,编译产物如下: "图片自定义高度" height="" width="" 选择对应的平台的命令行,window 使用 .bat 文件

ChkBugReport bugreport-meizu_18X_CN-RKQ1.210614.002-2022-12-07-11-11-54.zip

这样可以直接解析日志报告文件,并生成 html 报告到 bugreport-meizu_18X_CN-RKQ1.210614.002-2022-12-07-11-11-54_out文件夹 "图片自定义高度" height="" width="" 打开 index.html,就可以快速查看 各种log、ANR、错误 等等信息 "图片自定义高度" height="" width=""

Battery Historian

Battery Historian 是一个检查电池相关的信息和事件的工具,支持Android 5.0 (API 21)和更高版本的Android设备。

它是一个go开发的web服务形式的工具,需要运行在 docker 内 由于无法访问 ~gcr.io~ 的docker镜像,这里使用别人 dockerhub 编译好的镜像 runcare/battery-historian

docker run -it -d -p 9999:9999 runcare/battery-historian --port 9999

访问 http://localhost:9999 就可以打开页面,可以上传上面生成的报告zip文件进行分析。

这个工具主要是用于分析电池功耗相关的数据,对系统异常等信息没有显示。

"图片自定义高度" height="" width=""

除了使用docker快速运行以外,也可以在本地编译,不过这里不过多介绍了,可以参考github文档。

结束

看到这里,系统报告的收集和查看基本上就这些了,不过 bugreport 对日志的记录有实效和大小限制,只能导出近期的报告,如果app出现问题需要排查,尽早的导出日志,避免关键信息被覆盖丢失。

如果感兴趣的可以了解一下adb bugreport 的源码实现,这些文件怎么生成的,这里不过多介绍。

相关链接

ChkBugReport.zip下载

adb burgrport 源码篇

doc 阅读 bug 报告

Github ChkBugReport Github Battery Historian

Android adb 下载

本文转自 [https://juejin.cn/post/7175429654374236218],如有侵权,请联系删除。

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值