开端

开发中触摸的除了代码以外,最多的可能便是日志的。 像Android日志检查,最简略的便是这样:

adb logcat

然后体系日志就会连绵不断的在控制台输出,其中包括了各种咱们关心的重要的调试信息。

Android 系统报告收集和查看
可是这仅仅一种合适开发调试的检查方式,有没有其他方法呢。

答案是必定的,现在应用商店供给了一些自动化测验,对测验失利的设备可能会供给一些体系日志,失利的原因可能是安装失利、运转时溃散、ANR等等,有没有想过这些日志是怎样生成的呢,关于测验小伙伴怎样在测验设备上搜集体系日志呢,下面就介绍一种 android 内置的日志搜集办法。

搜集陈述

好在 android 交心的供给了一个东西 bugreportAndroid 的所有版本都支撑经过 adb获取 bug 陈述, 所以怎样运用呢: 假设发现应用呈现了溃散等反常情况时,不要紧张手机连接电脑,输入指令(这里不对 adb 环境的做介绍,后边有下载链接)

adb bugreport

静静等待陈述生成并导出,结束后会有如下输出,会有一个zip包在当前途径下生成

Android 系统报告收集和查看

咱们能够直接解压这个zip来翻开

Android 系统报告收集和查看
这里只标识了一些重要的文件意义,其他的无法直接检查,需求凭借到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

这里不对它的编译做过多介绍,编译产品如下:

Android 系统报告收集和查看
挑选对应的渠道的指令行,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文件夹

Android 系统报告收集和查看
翻开 index.html,就能够快速检查 各种log、ANR、过错 等等信息
Android 系统报告收集和查看

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文件进行剖析。

这个东西主要是用于剖析电池功耗相关的数据,对体系反常等信息没有显示。

Android 系统报告收集和查看

除了运用docker快速运转以外,也能够在本地编译,不过这里不过多介绍了,能够参阅github文档。

结束

看到这里,体系陈述的搜集和检查基本上就这些了,不过 bugreport 对日志的记载有实效和大小限制,只能导出近期的陈述,如果app呈现问题需求排查,尽早的导出日志,避免要害信息被掩盖丢掉。

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

相关链接

ChkBugReport.zip下载

adb burgrport 源码篇

doc 阅读 bug 陈述

Github ChkBugReport Github Battery Historian

Android adb 下载