当前位置: 首页 > news >正文

第三部分 日志系统实战进阶

第三部分 日志系统实战进阶

第7章 logcat工具完全指南

在前面的章节中,我们深入理解了Android日志系统的架构、启动流程与日志全链路。现在,让我们聚焦于最常用的日志查看工具——logcat。logcat不仅是简单的日志查看器,更是系统工程师的"瑞士军刀"。掌握logcat的各种用法和高级技巧,能极大提升日志分析效率,快速定位问题根源。本章将从基础操作开始,逐步深入到高级技巧,帮助你成为logcat使用专家。

7.1 基础操作回顾

7.1.1 查看实时日志

logcat最基础的用法是查看实时流动的系统日志。

基本命令

# 最简单的用法:连接设备后直接查看日志adb logcat# 或者用logcat的完整路径(在设备上)adb shell logcat

运行这条命令后,你会看到源源不断的日志输出,就像一条流动的信息河流:

05-20 14:30:00.123 1234 1235 I ActivityManager: Starting Activity: com.example.app 05-20 14:30:01.456 1234 1240 W WindowManager: Window size mismatch: expected 1080x2340, got 1080x2244 05-20 14:30:02.789 5678 5679 E MediaServer: Failed to initialize audio device

每列的含义

列位置含义示例
第1列日期与时间05-20 14:30:00.123
第2列PID(进程ID)1234
第3列TID(线程ID)1235
第4列日志等级I(INFO)、W(WARN)、E(ERROR)
第5列TAG(标签)ActivityManager
第6列日志内容Starting Activity: com.example.app
7.1.2 清空日志缓冲区

在调试过程中,旧日志会干扰视线。可以用-c参数清空所有缓冲区的日志:

# 清空所有缓冲区的日志adb logcat-c# 清空特定缓冲区(只清空main缓冲区)adb logcat-bmain-c# 查看清空前的缓冲区使用情况adb logcat-g# 输出示例:# /dev/log/main 256K 128K 50%# /dev/log/system 256K 200K 78%

使用场景

  • 在开始新的测试前清空日志,确保看到的都是新产生的日志
  • 在复现问题后立即清空,方便保存只包含问题相关日志的文件
7.1.3 退出与保存

在查看日志的过程中,有时需要保存日志供后续分析。

暂停与退出

# Ctrl+C:中断当前logcat的实时输出# logcat会自动重新连接# 持续运行并保存到文件(最常用的保存方法)adb logcat>logcat_output.txt# 或使用tee命令,既在终端显示又保存到文件adb logcat|teelogcat_output.txt

完整日志导出(保留所有缓冲区的历史日志):

# 导出当前缓冲区中的所有日志(不是实时的,是一次性导出)adb logcat-d>all_logs.txt# -d参数表示"dump"(转储),导出所有已有日志并退出# 这对保存特定时刻的日志快照很有用

7.2 过滤技巧大全

logcat输出往往很庞杂,一秒钟可能产生数百条日志。有效的过滤才是快速定位问题的关键。

7.2.1 按TAG过滤

TAG是日志的标签,用于标识日志来源(如ActivityManager、MainActivity等)。

精确过滤

# 只看ActivityManager的日志adb logcat-sActivityManager# 看多个特定TAG(用空格分隔)adb logcat-sActivityManager WindowManager# 效果:其他TAG的日志都被过滤掉,只显示指定TAG

按TAG和等级组合过滤

# 只看ActivityManager的INFO级及以上日志adb logcat ActivityManager:I# 只看ActivityManager的ERROR和FATAL日志adb logcat ActivityManager:E

使用通配符过滤

# 看所有以"Activity"开头的TAGadb logcat *Activity*# 看所有以"Manager"结尾的TAGadb logcat *Manager

实战例子

# 调试启动流程:重点关注AMS和Zygote的日志adb logcat-sActivityManager Zygote# 调试UI问题:关注WMS和View的日志adb logcat-sWindowManager View
7.2.2 按等级过滤

日志等级从低到高:V(冗余) → D(调试) → I(信息) → W(警告) → E(错误) → F(严重)

按等级过滤

# 只看ERROR及以上等级的日志(ERROR、FATAL)adb logcat *:E# 只看WARNING及以上等级adb logcat *:W# 只看INFO及以上等级(排除DEBUG和VERBOSE)adb logcat *:I

针对特定TAG的等级过滤

# ActivityManager的DEBUG日志adb logcat ActivityManager:D# 所有TAG的ERROR日志 + ActivityManager的DEBUG日志adb logcat *:E ActivityManager:D

实战例子

# 快速定位系统问题:只看ERROR以上的日志adb logcat *:E# 调试应用:看所有级别,但优先关注ERRORadb logcat|grep-E"ERROR|FATAL|E/"# 查看启动过程的关键信息adb logcat *:I|head-100# 只看最前100行INFO级日志
7.2.3 按PID/TID过滤

有时需要只看某个进程或线程的日志。

按PID过滤

# 先查找进程IDadb shellps|grepcom.example.app# 输出:u:r:untrusted_app:s0 1234 567 3456 8904 SyS_epoll_wait eee46ba4 S com.example.app# 1234就是PID,然后过滤这个进程的所有日志adb logcat--pid=1234# 简短形式adb logcat--pid1234

按多个PID过滤

# 同时看两个进程的日志adb logcat--pid1234--pid5678

按TID过滤(线程ID):

# 只看特定线程的日志(需要手动指定TID)adb logcat|grep" 1240 "# 假设1240是目标线程ID

实战例子

# 问题:某应用频繁崩溃# 步骤1:找到应用PIDadb shell pidof com.example.app# 步骤2:只看这个应用的日志(包括主进程和fork的子进程)adb logcat--pid1234|head-1000# 步骤3:查找异常日志adb logcat--pid1234|grep-E"ERROR|crash|exception"
7.2.4 按缓冲区过滤

不同缓冲区存储不同类型的日志。只看关心的缓冲区能减少无关信息。

缓冲区列表

缓冲区内容使用场景
main应用日志调试应用、第三方应用
system系统服务日志调试AMS、WMS等系统服务
radio通信相关日志调试网络、蓝牙、通话
events结构化事件日志分析应用启动、ANR等
crash崩溃日志查看应用/系统崩溃
all所有缓冲区全面诊断

按缓冲区过滤

# 只看main缓冲区(应用日志)adb logcat-bmain# 只看system缓冲区(系统服务日志)adb logcat-bsystem# 同时看main和system缓冲区adb logcat-bmain-bsystem# 看所有缓冲区(默认行为)adb logcat-ball

实战例子

# 调试应用问题adb logcat-bmain-sMainActivity# 调试系统服务问题adb logcat-bsystem-sActivityManager# 查找所有崩溃信息adb logcat-bcrash-ball|grep-icrash
7.2.5 按时间过滤

需要查看特定时间范围的日志。

时间过滤参数

# 查看最近5分钟的日志(实时输出)adb logcat-t5m# 查看最近10小时的日志adb logcat-t10h# 从指定时间点开始看日志adb logcat--since"2024-05-20 14:30:00"# 查看自设备启动后的日志adb logcat--since"1970-01-01 00:00:00"

时间单位说明

  • s= 秒
  • m= 分钟
  • h= 小时
  • d= 天

实战例子

# 问题:发生在下午3点左右,需要查看当时的日志adb logcat-t30m>debug_log.txt# 保存最近30分钟的日志# 查看启动阶段的日志(假设启动耗时2分钟)adb logcat-t5m-bsystem# 系统启动后立即运行,看最近5分钟
7.2.6 组合过滤与高级技巧

logcat支持复杂的过滤条件组合,可以用grep、awk等工具进一步加工。

基础组合

# 结合TAG、等级、缓冲区的多维度过滤adb logcat-bsystem-sActivityManager:I WindowManager:W# 看system缓冲区中的INFO以上日志adb logcat-bsystem *:I# 看最近1小时内的ERROR日志adb logcat-t1h|grep-i"ERROR"

使用grep进行文本匹配

# 只看包含"crash"关键词的日志adb logcat|grep-icrash# 只看不包含"DEBUG"的日志(-v反选)adb logcat|grep-vDEBUG# 组合:看system缓冲区中包含"failed"但不包含"retry"的日志adb logcat-bsystem|grep"failed"|grep-v"retry"

使用awk进行高级处理

# 统计不同TAG出现的次数adb logcat|awk-F' ''{print $6}'|sort|uniq-c|sort-rn|head-10# 提取特定时间范围的日志(14:30-14:35之间)adb logcat|awk'$1=="05-20" && $2>="14:30:00" && $2<="14:35:00"'# 按PID分组统计日志数adb logcat|awk'{print $2}'|sort|uniq-c|sort-rn|head-5

使用正则表达式

# 匹配所有数字PID的日志(1000-9999)adb logcat|grep-E" [0-9]{4} "# 匹配包含数字或下划线的TAGadb logcat|grep-E"[A-Za-z0-9_]+:"# 提取特定格式的日志(如异常堆栈)adb logcat|grep-E"at .+\(.*\.java:[0-9]+\)"

实战例子

# 完整案例:找出主线程阻塞的日志# 首先获取应用PIDAPP_PID=$(adb shell pidof com.example.app)# 然后只看这个应用、等级为WARN或ERROR、包含"ANR"或"timeout"的日志adb logcat--pid$APP_PID|grep-E"(ANR|timeout)"|grep-E"(W|E)/"# 更复杂的例子:统计过去1小时内,每个TAG产生的ERROR日志数adb logcat-t1h|grep-E"E/"|\awk-F' ''{print $6}'|\sort|uniq-c|sort-rn

7.3 格式定制

logcat的输出格式可以自定义,不同的格式适合不同的分析场景。

7.3.1 threadtime格式(默认)

这是logcat的默认格式,包含最详细的信息。

adb logcat-vthreadtime# 或简写adb logcat-vtime

输出示例

05-20 14:30:00.123 1234 1235 I ActivityManager: Starting Activity

每列含义

  • 05-20= 月-日
  • 14:30:00.123= 时:分:秒.毫秒
  • 1234= PID(进程ID)
  • 1235= TID(线程ID)
  • I= 日志等级(I=INFO)
  • ActivityManager= TAG
  • := 分隔符
  • Starting Activity= 日志内容

优点:信息最详细,适合详细分析

缺点:输出很长,可能看不清重点

7.3.2 brief格式(简洁)

这种格式只显示关键信息,很适合快速浏览。

adb logcat-vbrief

输出示例

I/ActivityManager(1234): Starting Activity W/WindowManager(5678): Window size mismatch E/MediaServer(9012): Failed to initialize audio

格式说明[等级]/[TAG]([PID]): [内容]

优点:简洁清晰,易于快速定位问题

缺点:丢失了时间戳和线程ID信息

7.3.3 time格式(仅时间+内容)

保留时间信息,但删除PID/TID,适合看时间序列。

adb logcat-vtime

输出示例

05-20 14:30:00.123 I/ActivityManager: Starting Activity 05-20 14:30:01.456 W/WindowManager: Window size mismatch 05-20 14:30:02.789 E/MediaServer: Failed to initialize audio

优点:包含时间戳,便于分析时间序列关系

缺点:看不到进程号

7.3.4 raw格式(仅内容)

只显示日志内容,去掉所有元信息。适合过滤和处理。

adb logcat-vraw

输出示例

Starting Activity Window size mismatch Failed to initialize audio device

优点:最简洁,用于管道处理或脚本分析

缺点:丢失所有上下文信息

7.3.5 其他有用的格式
# long格式:最详细,每条日志占多行adb logcat-vlong# json格式(AOSP 12+):便于程序解析adb logcat-vjson# printable格式:确保所有字符可打印(避免乱码)adb logcat-vprintable

选择格式的建议

场景推荐格式原因
实时调试threadtime信息详细
快速浏览brief简洁清晰
时间分析time保留时间戳
脚本处理raw易于解析
学习研究long最详细
7.3.6 实战例子
# 问题调试:看最多的信息(用brief格式聚焦问题)adb logcat-vbrief|grep-ierror# 性能分析:看时间线(用time格式看事件顺序)adb logcat-vtime-bsystem|grep-E"boot|startup|ready"# 自动化处理:用raw格式提取纯内容adb logcat-vraw|grep"keyword">keywords_only.txt# 复杂分析:用long格式看完整上下文adb logcat-vlong|grep-A5-B5"crash"

7.4 日志导出与保存

调试问题时,往往需要保存日志供后续分析或提交给他人。

7.4.1 导出到文件

基本导出

# 最简单的导出(会覆盖已有文件)adb logcat>logcat.txt# 不覆盖,追加到文件末尾adb logcat>>logcat.txt# 导出同时在终端显示(推荐)adb logcat|teelogcat.txt

导出指定内容

# 导出特定TAG的日志adb logcat-sActivityManager|teeam_logs.txt# 导出ERROR及以上的所有日志adb logcat *:E|teeerror_logs.txt# 导出特定缓冲区adb logcat-bsystem|teesystem_logs.txt# 导出特定时间范围adb logcat-t1h|teelast_hour.txt

一次性导出当前缓冲区中的所有日志

# 导出现有的所有日志并退出(不是实时输出)adb logcat-d>snapshot.txt# 导出特定格式的日志快照adb logcat-d-vlong>detailed_snapshot.txt
7.4.2 持续记录(后台运行)

有时需要在后台持续录制日志,待问题出现时再停止。

使用nohup后台运行

# 在后台持续记录日志,即使关闭终端也继续运行nohupadb logcat>logcat_$(date+%Y%m%d_%H%M%S).txt&# 后台记录,输出到带时间戳的文件adb logcat>logcat_$(date+%Y%m%d_%H%M%S).txt&# 查看后台任务jobs# 停止后台任务fg# 切换回前台Ctrl+C# 停止

使用screen或tmux(更专业的做法)

# 使用screen创建后台会话screen-Slogcat_session-d-madb logcat# 查看会话screen-ls# 连接到会话查看日志screen-rlogcat_session# 断开连接(保持后台运行)Ctrl+A, D# 停止会话screen-Slogcat_session-Xquit

定期导出(用脚本实现自动化)

#!/bin/bash# 脚本:定时导出日志LOG_DIR="./logs"mkdir-p$LOG_DIR# 每10秒导出一次日志快照whiletrue;doTIMESTAMP=$(date+%Y%m%d_%H%M%S)echo"Saving logcat snapshot at$TIMESTAMP"adb logcat-d>$LOG_DIR/logcat_$TIMESTAMP.txtsleep10done
7.4.3 定时抓取(结合cron)

如果需要在特定时间自动抓取日志(如每天固定时间)。

# 创建脚本:save_logcat.sh#!/bin/bashLOGDIR="/home/user/logs"TIMESTAMP=$(date+"%Y%m%d_%H%M%S")adb logcat-d>$LOGDIR/logcat_${TIMESTAMP}.txt# 配置定时任务crontab-e# 在crontab中添加以下行:# 每天上午10点执行一次010* * * /path/to/save_logcat.sh# 每小时执行一次0* * * * /path/to/save_logcat.sh# 列出已有的定时任务crontab-l
7.4.4 bugreport完整打包

bugreport生成一个完整的系统诊断报告,包含logcat、dumpsys和tombstone等。

# 生成bugreport(会自动创建zip文件)adb bugreport# 指定输出文件名adb bugreport output_dir/# 生成后会看到类似的输出:# bugreport completed: /path/to/bugreport-2024-05-20-14-30-00.zip

bugreport包含的内容

  • logcat日志(所有缓冲区)
  • dumpsys输出(所有系统服务的状态)
  • Tombstone文件(最近的崩溃信息)
  • 进程信息和内存映射
  • 内核日志(dmesg)
  • 电池统计信息

使用场景

# 场景1:发现系统bug,需要向Google提交adb bugreport# 生成报告后上传到Google# 场景2:现场保留证据adb bugreport bug_evidence_$(date+%Y%m%d).zip# 场景3:分析某一时刻的系统状态# 先清空缓冲区再做操作,然后立即生成bugreportadb logcat-c# ... 执行操作 ...adb bugreport
7.4.5 远程日志抓取

有时需要从远程设备抓取日志(如现场测试设备)。

基于SSH的远程logcat

# 场景:现场有一台设备,通过SSH连接sshuser@remote_host"adb logcat -d">remote_logcat.txt# 或持续实时监测sshuser@remote_host"adb logcat"|teeremote_logcat_realtime.txt

基于网络ADB的远程logcat

# 场景:设备通过网络连接到adb# 第一步:设置设备的ADB网络连接adb connect192.168.1.100:5555# 第二步:导出日志adb-s192.168.1.100:5555 logcat>remote_device.txt

7.5 高级技巧

7.5.1 彩色显示与可视化

标准logcat的输出是单色的,不易区分。可以使用第三方工具改善体验。

使用pidcat工具

pidcat是一个Python脚本,可以为logcat的输出添加彩色,按PID着色。

# 安装pidcatpipinstallpidcat# 或从GitHub克隆gitclone https://github.com/JakeWharton/pidcat.gitcdpidcatchmod+x pidcat.py# 使用pidcat(比logcat更易读)pidcat com.example.app# 显示所有包,按PID着色pidcat# 只看特定TAG的彩色输出pidcat-tActivityManager

pidcat的优势

  • 自动按进程着不同颜色
  • 易于区分日志等级
  • 更易发现模式和异常
7.5.2 多设备管理

如果连接了多个设备或模拟器。

# 列出所有连接的设备adb devices# 输出示例:# List of attached devices# emulator-5554 device# FA4AY1A5280 device# 192.168.1.100:5555 device# 指定设备查看日志adb-semulator-5554 logcat# 或用完整的序列号adb-sFA4AY1A5280 logcat# 只用IP和端口adb-s192.168.1.100:5555 logcat# 同时监视多个设备(用脚本)#!/bin/bashfordevicein$(adb devices|grepdevice|awk'{print $1}'|grep-v"devices");doecho"=== Monitoring$device==="adb-s$devicelogcat>logcat_${device}.txt&done
7.5.3 日志分析脚本

使用脚本自动化日志分析。

Python脚本示例

#!/usr/bin/env python3importsubprocessimportrefromcollectionsimportdefaultdictfromdatetimeimportdatetimedefanalyze_logcat():"""分析logcat中的错误和警告"""# 获取logcat输出proc=subprocess.Popen(['adb','logcat'],stdout=subprocess.PIPE,text=True)error_count=defaultdict(int)tag_stats=defaultdict(int)try:forlineinproc.stdout:# 提取TAG和等级match=re.search(r'([A-Z])/(\w+)',line)ifmatch:level,tag=match.groups()tag_stats[tag]+=1# 计数ERROR和FATALiflevelin['E','F']:error_count[tag]+=1print(f"[ERROR]{line.strip()}")exceptKeyboardInterrupt:print("\n\n=== 统计报告 ===")print(f"总日志条数:{sum(tag_stats.values())}")print
http://www.jsqmd.com/news/1076677/

相关文章:

  • 防火墙原理与技术
  • KAN神经网络实操指南:从数学定理到科学建模可解释部署
  • 生成式AI在软件开发中的人机协同实践指南
  • 2026小程序开发系统多平台功能与应用全面解析
  • 架构 - 理解架构的演进
  • 3分钟快速上手:Obsidian Excel转Markdown表格完整指南
  • 在macOS上实现Intel无线网卡驱动的技术挑战与解决方案:itlwm项目深度解析
  • Log4j2漏洞复现与防御:从JNDI注入到远程代码执行实战
  • 2026年苏州玻璃间隔纸哪家公司好:无尘度高,抗静电性能强
  • BilldDesk:重新定义开源远程桌面控制的跨平台解决方案
  • 高防 CDN 工作原理拆解 从流量识别到攻击拦截的全流
  • 当微信机器人遇见大模型:如何让算法更懂你的语义接口?
  • ZeroTier:把地球变成一个局域网
  • 我在飞书里养了个“分身”——私聊喊它办事,群里 @ 它干活,还能替我传话
  • 爬虫转大模型:真实开发里的落地路径
  • 层次聚类实战指南:从树状图到可解释业务分组
  • 3分钟掌握PPTist:免费网页版PPT制作工具的完整指南
  • 现场签约40项目!美豪品牌家族品鉴会圆满举行,艺科交出整合赋能答卷
  • Selenium vs Cypress vs Playwright:现代Web自动化测试框架横向评测与选型指南
  • saphana数据库Alert告警:check type: id 130 alert check own certificate expiration date
  • 为什么有的人偏爱 Mac
  • 【Springboot毕设全套源码+文档】基于Java的篮球馆预约系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • 计算机毕业设计之基于ssm的图书分享管理系统
  • 哔哩下载姬视频旋转功能深度解析:从元数据处理到批量操作
  • AIGC赋能测试用例生成:工程化实践与效率革命
  • SGLang:每天处理万亿 token 的 LLM 推理引擎
  • 全国医美机构选 GEO 服务商避坑指南,实测 12 家套路 AI 获客公司曝光
  • Anthropic把Claude塞进Slack、Agent框架对决开始、阿里云Agent接手7x24运维——科技圈今天不无聊
  • 移动云能够提供哪些类型的云服务?
  • 森利威尔 SL3036HB 宽压 8-150V 可调输出4.2-30V 2.5A 降压恒压IC