一、前言

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

二、命令简介

选项 描述 eg
-s 输出指定 tag 的日志,相当于过滤器表达式 '*:S' logcat -s tag
-f <file> 设置logcat 内容保存的位置,默认是stdout logcat -f sdcard/log.txt
-r <kbytes> 每输出 <kbytes> 时轮替日志文件,默认是16 必须配合 -f (暂不明白) logcat -f sdcard/log.txt -r 1
-n <count> 设置日志输出的最大数目, 需要 -r 参数 暂不明白
-v <format> 设置日志消息的输出格式。详见下文 格式化输出 logcat -v thread
-D 输出各个日志缓冲区之间的分隔线 logcat -D ...
-c 清除(清空)所选的缓冲区并退出,默认清除 main、system 和 crash logcat -c / -b all -c
-d 将日志转储到屏幕并退出 logcat -d > log.txt
-e <expr> 输出正则匹配的日志消息 logcat -e 匹配数据 -m 5
-m <count> 输出 <count> 行后退出 ......
-t <count> 仅输出最新的行数,此选项包括 -d 功能 logcat -t 5
-t '<time>' 输出自指定时间以来的最新行,此选项包括 -d 功能 logcat -t '01-26 20:52:41.820'
-g 获取指定日志缓冲区的大小并退出 logcat -g
-G 设置日志环形缓冲区的大小,可以在结尾处添加 K 或 M logcat -G 2M
-b 加载可供查看的日志缓冲区,更多可见下文 日志缓冲区 logcat -b system
-B 以二进制文件形式输出日志 ......
-S 在输出中包含统计信息,以识别和定位日志垃圾信息发送者 ......
--pid=<pid> 仅输出来自给定 PID 的日志 logcat --pid=4355

三、日志缓冲区

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

缓冲区 描述 eg
radio 输出通信系统的日志,包含无线装置/电话相关消息 logcat -b radio
events 输出event模块的日志 logcat -b events
main 主日志缓冲区(默认),不包含系统和崩溃日志消息 logcat -b main
system 输出系统日志 logcat -b system
crash 输出崩溃日志 logcat -b crash
all 输出所有缓冲区日志 logcat -b all
default 输出main、system、crash缓冲区日志 logcat -b default

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

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 的输出格式,以显示特定的元数据字段:

格式 描述 eg
brief 显示优先级、标记以及发出消息的进程的 PID ......
long 显示所有元数据字段,并使用空白行分隔消息 ......
process 仅显示 PID ......
raw 显示不包含其他元数据字段的原始日志消息 ......
tag 仅显示优先级和标记 ......
thread 旧版格式,显示优先级、PID 以及发出消息的线程的 TID ......
threadtime (默认值)显示日期、调用时间、优先级、标记、PID 以及发出消息的线程的 TID ......
time 显示日期、调用时间、优先级、标记以及发出消息的进程的 PID ......
color 使用不同的颜色来显示每个优先级 ......
descriptive 显示日志缓冲区事件说明。此修饰符仅影响事件日志缓冲区消息,不会对其他非二进制文件缓冲区产生任何影响 ......
epoch 显示自 1970 年 1 月 1 日以来的时间(以秒为单位) ......
monotonic 显示自上次启动以来的时间(以 CPU 秒为单位) ......
printable 确保所有二进制日志记录内容都进行了转义 ......
uid 如果访问控制允许,则显示 UID 或记录的进程的 Android ID ......
usec 显示精确到微秒的时间 ......
UTC 显示 UTC 时间 ......
year 将年份添加到显示的时间 ......
zone 将本地时区添加到显示的时间 ......

优先级:

选项 描述 eg
V –Verbose(最低优先级) adb logcat *:v
D – Debug adb logcat *:d
I – Info adb logcat *:i
W – Warning adb logcat *:w
E – Error adb logcat *:e
F – Fatal adb logcat *:f
S – Silent adb logcat *:s

五、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));
}

作者:猫咪不吃鱼
链接:https://www.jianshu.com/p/26252ee91726
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Android 日志系统分析(三):logcat相关推荐

  1. Android10.0 日志系统分析(三)-logd、logcat读写日志源码分析-[Android取经之路]

    摘要:本节主要来讲解Android10.0 logd.logcat读写日志源码内容 阅读本文大约需要花费20分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,Andro ...

  2. Android日志系统分析之开篇

    在android系统中, 提供了一个轻量级的日志系统.该日志系统基于在内核中实现的一个字符设备驱动 logger(misc字符设备驱动).通过该字符设备驱动,android分别提供了C/C++和Jav ...

  3. Android日志系统分析之日志设备驱动程序代码阅读

    android日志系统中定义了设备驱动的实现代码位于kernel/common/drivers/staging/android/logger.h和kernel/common/drivers/stagi ...

  4. Android编译系统分析三:make完整编译android系统

    这篇博客的目标是摸清楚默认编译整个android系统时代码的流程. 当我们执行make的时候,会查找当前的Makefie文件或者makefile文件并且执行,在android顶级源码目录下面,确实有个 ...

  5. Android 编译系统分析(三)

    自Android开源以来,引起了嵌入式行业一股热潮,很多嵌入式开发者表示对Android有很强的兴趣,并下载Android源码进行编译和移植.Android源码的巨大(repo下来,大概2G)给人以A ...

  6. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化-[Android取经之路]

    摘要:本节主要来讲解Android10.0 日志系统的架构分析,以及logd.logcat的初始化操作 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...

  7. Android10.0 日志系统分析(一)-logd、logcat 指令说明、分类和属性-[Android取经之路]

    摘要:本节主要来讲解Android10.0 日志系统的logd.logcat相关指令说明.日志分类和常用日志属性 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Andro ...

  8. Android10.0 日志系统分析(四)-selinux、kernel日志在logd中的实现​-[Android取经之路]

    摘要:本节主要来讲解Android10.0 selinux.kernel日志在logd中的实现,包括LogAudit.LogKlog的源码分析 阅读本文大约需要花费15分钟. 文章首发微信公众号:In ...

  9. Android日志[进阶篇]三-Logcat 命令行工具

    Android日志[进阶篇]一-使用 Logcat 写入和查看日志 Android日志[进阶篇]二-分析堆栈轨迹(调试和外部堆栈) Android日志[进阶篇]三-Logcat命令行工具 Androi ...

最新文章

  1. java api中的设计模式_Java API 设计模式之策略(Strategy)
  2. 陈老师Linux内核内存寻址导学
  3. Linux基本网路配置及软件包的安装
  4. android 双 webview,Android webview加载页面
  5. 番茄日志发布1.0.3版本-增加Kafka支持
  6. bs架构 erp 进销存_从依赖经验到用柔性ERP,企业少走了多少弯路?
  7. [luogu3380][bzoj3196]【模板】二逼平衡树【树套树】
  8. okhttp 工具类_日语学习工具推荐,小白必备!
  9. 传言成真 天融信收购傲天动联
  10. 田间小麦病害自动诊断系统(野外复杂环境)
  11. jquery 动态添加,降低input表单的方法
  12. 全国乡镇边界及名称的下载与格式转换方法(水经注万能地图X3.1+CASS10.1.5组合拳)
  13. 苹果8a1660是什么版本_苹果7a1660是什么版本
  14. 再更新:2022 京东/淘宝双11活动一键自动完成任务脚本app来了,顺便说个事情...
  15. Pascal词法分析器用java实现
  16. 数据结构---线性表
  17. LaTeX的正负号写法
  18. 升平,景玉军.计算机虚拟技术在高职汽车维修教学中的应用研究[j].,汽车新技术教学方法探讨...
  19. 锚点是什么?锚点的使用
  20. bmi计算 python_python tkinter bmi计算

热门文章

  1. JavaWeb 访问JSP报错解决--org.apache.jasper.compiler.Compiler generateClass
  2. 一个比较好、中文说明的emacs配置文件 1
  3. Android 安卓动画 补间动画 - 组合(四个动画) 动画
  4. 在路上—Tinyfool的程序员生涯(大学篇)
  5. EasyExcel简单的写和多table的写
  6. 工控主板启动不显示的故障原因
  7. SGU 103 Traffic Lights
  8. 2020计算机考研院校推免,2020考研:热门院校推免比例超90%?他们说尝试了就不后悔!...
  9. 相机螺纹接口:C口和CS口
  10. 天翼云应用实操-天翼云资源池间通过IPSEC实现高速互通