失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android 日志系统分析(三):logcat

Android 日志系统分析(三):logcat

时间:2019-09-04 02:01:21

相关推荐

Android 日志系统分析(三):logcat

一、前言

logcat作为读取日志的工具,相当于client 的角色;在前两篇文章中,关于logcat如何与其他部分沟通获取日志信息的流程已经介绍的比较清晰,本文不在赘述,转而归纳一下logcat的一些常用指令,并对其中一些做详细分析

二、命令简介

三、日志缓冲区

Android日志系统为日志消息保留了多个环形缓冲区,但并非多有的日志消息都会发送到默认的环形缓冲区。这里可以采用logcat -b命令查看设备的其他缓冲区:

如果需要查看内核空间日志信息,可采用如下几种方式查看:

1、读取/proc/kmsg,命令如下

adb shell cat /proc/kmsg

读取/proc/kmsg属于消费型读取,读取之后再次读取不会显示已经读取过的日志信息

2、读取/dev/kmsg,命令如下

adb shell cat /dev/kmsg

读取/dev/kmsg会显示缓存区里面的所有日志信息。新写入的日志信息会不断累加到日志缓冲器中

3、使用dmesg命令读取

adb shell dmesg

dmesg命令读取一次只显示一部分日志,非阻塞执行

四、格式化输出

使用-v命令来修改log的输出格式,以显示特定的元数据字段:

优先级:

五、logcat -f 命令详解

logcat -f命令可以将日志消息输出到指定的文件中。这里我们需要确定的一件事是logcat作为客户端的角色,会将通过liblog获得的日志信息进行格式解析、格式化处理,而liblog库本身并不存在保存、解析的功能。这里来对-f指令做一下解析:

logcat_main.cpp # main()---> logcat.cpp # android_logcat_run_command()---> __logcat(){......case 'f':if ((tail_time == log_time::EPOCH) && !tail_lines) {tail_time = lastLogTime(optctx.optarg);}// redirect output to a filecontext->outputFileName = optctx.optarg; //注释 ①break;......setupOutputAndSchedulingPolicy() //注释 ②while (...) { //注释 ③int ret = android_logger_list_read(logger_list, &log_msg);if (context->printBinary) {printBinary(context, &log_msg);} else {processBuffer(context, dev, &log_msg);}......}

5.1 注释① :解析 -f 指令

case 'f':if ((tail_time == log_time::EPOCH) && !tail_lines) {tail_time = lastLogTime(optctx.optarg);}// redirect output to a filecontext->outputFileName = optctx.optarg; //注释 ①break;

_logcat()函数中解析-f指令,设置日志输出文件。例如logcat -f sdcard/log.txt,则context->outputFileName赋值为sdcard/log.txt

5.2 注释② :设置输出路径

static void setupOutputAndSchedulingPolicy(android_logcat_context_internal* context, bool blocking) {if (!context->outputFileName) return;......// 打开文件获得 fd context->output_fd = openLogFile(context->outputFileName);if (context->output_fd < 0) {logcat_panic(context, HELP_FALSE, "couldn't open output file");return;}......}

5.3 注释③ :写入日志

while (...) { // 调用 liblog 库中的 android_logger_list_read 函数获取日志 int ret = android_logger_list_read(logger_list, &log_msg);if (context->printBinary) { // 根据上面获取的文件 fd ,将日志消息写入文件printBinary(context, &log_msg);} else {processBuffer(context, dev, &log_msg);}

printBinary()函数为例:

logcat.cpp # printBinary() :

void printBinary(android_logcat_context_internal* context, struct log_msg* buf) {size_t size = buf->len();TEMP_FAILURE_RETRY(write(context->output_fd, buf, size));}

作者:猫咪不吃鱼

链接:/p/26252ee91726

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

如果觉得《Android 日志系统分析(三):logcat》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。