众所周知,日志在应用产品的整个开发生命周期中发挥着重要的作用。例如:在软件开发过程中,错误日志可以帮助开发人员及时地识别出程序中的逻辑错误;而在将产品发布到市场之后,支持工程师可以通过分析错误日志,来解决各种疑难杂症。在我们常用的安卓(Android)系统中,各种日志默认是被集中式管理的。当然,市场上有许多可用来开发Android应用的工具,能够让应用开发程序员们编写出自定义的日志消息,以及特定日志语句定义的各种过滤器。目前,Android生态系统提供了不同类型的日志,其中包括:应用日志、系统日志、事件日志、以及广播日志(Radio Logs)。
日志记录系统的组成包括:内核驱动程序和内核缓冲区(用于存储Android日志消息),可用于创建日志条目和访问日志消息的C、C++和Java类,可用于查看日志消息(logcat)的独立程序,以及具有查看日志和过滤来自主机的日志消息(通过eclipse或ddms)等组件。
Android系统的Linux内核有着四个不同的日志缓冲区,它们针对系统的不同部分提供着日志记录。例如:通过文件系统里/dev/log的设备节点,我们可以访问到Android的四个日志缓冲区:main、event、radio和system。其中main日志用于应用程序,event用于系统事件信息,radio用于电话相关信息,而system则与低级系统消息和调试有关。
日志中的每一条消息都包含有一个标记。通过此类标记我们可以获悉:该消息来自系统或应用的哪一部分、时间戳(该消息何时到达的)、消息的日志级别(或消息所代表的事件优先级)、以及日志消息体本身(有关错误、异常或信息等详细的说明)。
Android系统中的四大日志类型:
1.应用日志
使用android.util.Log类方法,将不同优先级的消息写到日志中。
利用各种Java类,以字符串的形式静态声明它们的标记,并传递给日志方法。
日志方法可用来标识消息的“优先级”(或日志级别)。
各种消息检索工具(logcat)在处理日志时,可以按标识或优先级来进行过滤。
2.系统日志
使用android.util.Slog类,来编写具有不同优先级的消息、及其关联消息。
许多Android框架类都能够将系统日志(可能比较杂乱)与应用日志消息区分开来。
格式化的消息是通过C/C++库被传递到内核驱动的,该驱动能够将消息存储到适当的缓冲区(如:系统缓冲区)中。
3.事件日志
使用android.util.EventLog类创建事件日志消息,此类消息通常为二进制格式。
日志条目包含了二进制标记代码,并跟随着二进制参数。
消息标记代码通常被存储在系统的/system/etc/event-log-tags中。
每个消息都带有日志消息的字符串,以及指向该条目关联(存储)值的代码。
4.广播日志
作用于与电话(调制解调器)相关的信息。
日志条目由二进制标签代码和消息所组成,可用于提供各种类型的网络信息。
日志记录系统会自动将带有特定标记的消息,路由到radio缓冲区中。
Android上日志格式
在Android系统里常见的日志格式为:tv_sectv_nsec priority pidtid tag messageLen Message。其中:
tag:日志标签。
tv_sec&tv_nsec:日志消息的时间戳。
pid:来自日志消息的进程ID。
tid:线程ID。
priority的值可参照如下规律,按照从低到高的顺序排列:
V-详细(Verbose,最低优先级)*
D-调试(Debug)*
I-信息(Info)*
W-警告(Warning)*
E-错误(Error)*
F-致命(Fatal)*
S-静默(Silent,最高优先级,但不打印任何内容)*
日志文件位置
原则上,Android的各项日志(包括崩溃日志)可以被存储在多处,且无标准化目录(即:由系统的ROM所特定)的要求。在此,我们介绍一些常用且常见的目录:
/data/anr:Dalvik(译者注:是Google自行设计的用于Android平台的虚拟机。)会在ANR处写入栈的跟踪,即“应用无响应(Application Not Responding)”,同时也称为“强制关闭(Force-Close)”。
/data/dontpanic:此处包含了一些崩溃日志,以便实现各种跟踪。
/data/kernelpanics:此处存储了与“内核错误(kernel panic)”相关的日志。
/data/tombstones:此处会包含多个tombstone_nn文件(nn是从0到10的数字,也就是说,在超过10以后需要重新计数)。
“Log”相关的命令行工具
在实际项目中,我们可以通过各种应用程序或命令行工具,从设备或仿真器上捕获在Android上产生的相关日志,进而将它们共享给各类开发人员或维护人员,以便他们开展深入的分析。下面是三个常用的命令:
adb logcat:显示当前Android系统所有类型的日志。
adb logcat -v threadtime:在显示内容中包含日期和时间。
adb logcat -v threadtime> logfile.txt:将日志存储在logfile.txt中。
实用的过滤器模式
为了减少数据量,您可以通过在adb命令(请参见-- https://www.pcloudy.com/executing-adb-shell-commands/)中使用如下过滤器(filter),来缩减日志的总量。当然,您也可以使用此类过滤器,来搜索用户Android设备上的日志文件。
adb logcat -f:将所有日志保存到一个文件中。
adb logcat“*:E”:获取所有的致命错误信息。
adb logcat | grep -i “foo.example.”:获取与“foo.example.*”相关的所有日志并标记。
adb logcat“application_or_tag_name:*”“*:S”:按应用名称获取所有的日志。
adb logcat -b events “gsm_service_state_change” “*:S”:获取所有GSM的状态更改。
adb logcat -b radio:获取所有的广播事件。
日志分析
至此,我们对Android的日志系统有了基本的了解。在实际分析中,我们通常会关注两类应用日志,它们分别是:
调试日志–在开发和测试阶段产生的日志文件。
生产日志–由最终用户在使用过程中直接生成的文件。
我们可以使用诸如GoogleLogTool和SonyLogTool之类的工具,通过采用过滤器模式,进行深入的分析。
标签: 日志