使用 logcat 命令
过滤日志输出
每一条日志消息都有一个标记和优先级与其关联。
标记是一个简短的字符串,用于标识原始消息的来源 ( 例如 "View" 来源于显示系统 ) 。
优先级是下面的字符,顺序是从低到高 :
V — 明细 ( 最低优先级 )
D — 调试
I — 信息
W — 警告
E — 错误
F — 严重错误
S — 无记载 ( 最高优先级,没有什么会被记载 )
通过运行 logcat ,可以获得一个系统中使用的标记和优先级的列表,观察列表的前两列,给出的格式是 <priority>/<tag> 。
如果想要减少输出的内容,可以加上过滤器表达式进行限制,过滤器可以限制系统只输出感兴趣的标记 - 优先级组合。
过滤器表达式的格式是 tag:priority ... ,其中 tag 是标记, priority 是最小的优先级, 该标记标识的所有大于等于指定优先级的消息被写入日志。也可以在一个过滤器表达式中提供多个这样的过滤,它们之间用空格隔开。
下面给出的例子是仅输出标记为“ ActivityManager ”并且优先级大于等于“ Info ”和标记为“ MyApp ”并且优先级大于等于“ Debug ”的日志:
adb logcat ActivityManager : I MyApp : D *: S
上述表达式最后的 *:S
用于设置所有标记的日志优先级为 S ,这样可以确保仅有标记为“ View”(译者注:应该为 ActivityManager,原文可能是笔误)和“ MyApp”的日志被输出,使用 *:S
是可以确保输出符合指定的过滤器设置的一种推荐的方式,这样过滤器就成为了日志输出的“白名单”。
下面的表达是显示所有优先级大于等于“ warning ”的日志:
adb logcat *: W
如果在开发用电脑上运行 logcat
( 相对于运行运程 shell 而言 ) ,也可以通过 ANDROID_LOG_TAGS
环境变量设置默认的过滤器表达式:
export ANDROID_LOG_TAGS = "ActivityManager:I MyApp:D *:S"
需要注意的是,如果是在远程 shell 或是使用 adb shell logcat
命令运行 logcat
, ANDROID_LOG_TAGS
不会导出到模拟器或手机设备上。
控制日志格式
日志消息在标记和优先级之外还有很多元数据字段,这些字段可以通过修改输出格式来控制输出结果, -v
选项加上下面列出的内容可以控制输出字段:
brief — 显示优先级 /标记和原始进程的 PID (默认格式 )
process — 仅显示进程 PID
tag — 仅显示优先级 / 标记
thread — 仅显示进程:线程和优先级 / 标记
raw — 显示原始的日志信息,没有其他的元数据字段
time — 显示日期,调用时间,优先级 / 标记, PID
adb logcat -v time | grep yulin0227>yulin00396.txt
long —显示所有的元数据字段并且用空行分隔消息内容
可以使用 -v
启动 logcat
来控制日志格式:
adb logcat简单举例:
1、导入日志到sd卡
写入一个文件 adb logcat | grep yulin >yulin.txt
过滤多个条件
adb logcat | grep "TAG_DymanicImageView \|TAG_CoolWindWeatherActivity"
2 用adb命令查询数据库
zhangyl@zhangyl-desktop:~$ adb shell
ata/data/com.coolwind.weather/
root@android:/data/data/com.coolwind.weather # cd databases/
root@android:/data/data/com.coolwind.weather/databases # ls
weather.db
weather.db-journal
root@android:/data/data/com.coolwind.weather/databases #
root@android:/data/data/com.coolwind.weather/databases # sqlite3 weather.db //挂在数据库文件
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from weather ; //查具体表
adb shell
ps |grep com.testy.pac
kill -9 PID
adb shell ps |grep "music|camera" 查看进程 ID
adb logcat -v threadtime |grep PID 显示指定进程的Log
adb shell 无法识别设备问题排查:
1. 手机setting 是否开启了 USB调试模式;
2.adb kill-server;adb start-server;
3.设置usb权限
因为ubuntu这样的系统都是默认以非root身份在运行的,要使用usb调试,需要
sudo支持。
$ lsusb 查看USB端口设备状态
Bus 001 Device 010: ID 0bb4:0c87 High Tech Computer Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
列表中,Bus 001 Device 010: ID 0bb4:0c87 High Tech Computer Corp. 这一
行 为htc手机的usb使用端口,记录一下,id为0bb4(基于上所有的htc都是这个
ID)。
$sudo vim /etc/udev/rules.d/70-android.rules
加入以下内容:
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4",
ATTRS{idProduct}=="0c87",MODE="0666"
其中的idvendor idProduct指的是USB的ID可以使用lsusb查询得到。
比如我的是:
lsusb
Bus 001 Device 010: ID 0bb4:0c87 High Tech Computer Corp
ID 0bb4 就是idVendor ,0c87就是 idProduct
运行命令,重启udev:
$sudo chmod a+rx /etc/udev/rules.d/70-android.rules
$sudo service udev restart
4.查看用户根目录下的.android/ adb _usb.ini 是否有驱动地址
5. adb 环境变量是否设置
=========================================================================
adb install -r SecMms.apk
adb unstall
当安装时,使用 adb install XXX.apk
当希望保留程式的一些资料,使用覆盖安装,adb -r install XXX.apk
当卸载是,使用 adb uninstall com.XXX.XXX.apk (注意,要使用包名)
问题一:
当使用覆盖安装时出现下面的错误:Failure [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES]
原因是由于apk的签名有误,和之前pad中已经存在的程式签名不同,解决方法就是无法进行覆盖安装,
要先将已有程式卸载,再重新进行安装。这样一些程式原有配置等资料会不见,要做好备份。
问题二:
卸载原有程式后,执行安装语句时出现下面错误:Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE]
原因是由于之前程式可能为一个群组,共用同一个user id,新程式于原有程式冲突
检查是否卸载干净,保证全部都卸载后,再重新进行安装。
问题三:
在进行数据备份时,使用
adb pull /data/data/XXXX/XXX.db ./user/temp
或者使用
adb push ./user/temp/XXX.db /data/data/XXXX
会出现权限不足的问题。pad也是已经进行了破解
(使用的也是lenove的pad,在使用adb shell时就和一般破解过的不一样
进入shell以后,不是直接拿到root权限,而是su之后才能有root权限,
退出时,如果当前权限是root执行exit之后先回到一般权限,再执行一次exit才退出shell)
难道是因为破解不完全的问题吗?还是因为需要pad端作一些权限的设定??
另外,我其他破解过的pad都可以成功执行上面的语句。
也已经试过 chmod 777 /data/data/XXXX,更改文件夹的权限,可是仍然没有办法pull或push。
因为有时间紧迫,无奈之下,决定先将文件备份到/sdcard中。
在使用cp是发现,没有办法直接使用cp,原来需要用busybox进行拷贝
进入adb shell中,执行 busybox cp /data/data/XXXX/XXX.db /sdcard/tmp/XXX.db
这才搞定。不过上面无法pull或push的问题依然还是无解中,不知到那位可以告诉原因?
过滤多个条件:adb logcat | grep "TAG_yulin01\|TAG_yulin02"
简介:
本文介绍如何在 shell 命令行中过滤 adb logcat 输出的几个小技巧。
开发当中经常看到别人的 log 如洪水般瞬间刷满了屏幕,对自己有用的信息都被淹没了,影响心情也影响效率。下面是几个我所知道的过滤方法。
1. 只显示需要的输出,白名单
最方便的当然是通过管道使用 grep 过滤了,这样可以使用 grep 强大的正则表达式匹配。简单的匹配一行当中的某个字符串,例如 MyApp:
adb logcat | grep MyApp adb logcat | grep -i myapp #忽略大小写。 adb logcat | grep --color=auto -i myapp #设置匹配字符串颜色。更多设置请查看 grep 帮助。
进阶一点可以使用 grep 的正则表达式匹配。例如上一个例子会匹配一行中任意位置的 MyApp,可以设置为仅匹配 tag。默认的 log 输出如下,如果修改过输出格式相应的表达式也要修改。
I/CacheService( 665): Preparing DiskCache for all thumbnails.
可以看出 tag 是一行开头的第三个字符开始,根据这点写出表达式:
adb logcat | grep "^..MyApp"
根据这个格式也可以设置只显示某个优先级的 log,再匹配行首第一个字符即可。例如仅显示 Error 级别 tag 为 MyApp 的输出:
adb logcat | grep "^E.MyApp"
当然也可以匹配多个,使用 | 分割多个匹配表达式,要加转义符。例如要匹配 tag 为 MyApp 和 MyActivity 的输出:
adb logcat | grep "^..MyApp\|^..MyActivity" adb logcat | grep -E "^..MyApp|^..MyActivity" #使用 egrep 无须转义符
2. 过滤不需要的输出,黑名单
还是使用 grep,用法也跟上面的一样,加一个 -v 即可。例如要过滤 tag 为 MyApp 和 MyActivity 的输出:
adb logcat | grep -v "^..MyApp\|^..MyActivity" adb logcat | grep -vE "^..MyApp|^..MyActivity" #使用 egrep 无须转义符
3. 显示同一个进程的所有输出
有时一个程序里面的 tag 有多个,需要输出该程序(同一个 PID)的所有 tag;仅使用 tag 过滤有时也会漏掉一些错误信息,而一般错误信息也是和程序同一个 PID。还是通过 grep 实现,思路是先根据包名找到 pid 号,然后匹配 pid。写成 shell 脚本如下,参数是程序的 java 包名(如 com.android.media)。
1 |
#!/bin/bash |
2 |
packageName=$1 |
3 |
pid=`adb shell ps | grep
awk '{print $2}' ` |
4 |
adb logcat | grep --color=auto $pid |
4. 从当前开始显示
logcat 有缓存,如果仅需要查看当前开始的 log,需要清空之前的。
adb logcat -c && adb logcat
5. 过滤 log 文件
有时需要分析 log 文件,过滤 log 文件还是使用 grep。例如 log 文件为 myapp.log,要匹配 tag 为 MyApp 和 MyActivity 的输出,然后输出到 newmyapp.log:
cat myapp.log | grep "^..MyApp\|^..MyActivity" > newmyapp.log
Windows 下推荐使用 Notepad++,一个免费强大的记事本,支持正则表达式查找替换。可以高亮显示匹配内容,也可以删除不需要的内容。
以上的技巧主要用到了 grep,其实 logcat 本身也有过滤功能,可以根据 tag、优先级过滤 log,具体请参考 Android 官方文档 Reading and Writing Logs。如果喜欢使用图形界面,请参考 Using DDMS,DDMS 里面的 logcat 也可以同样过滤。