有时候会发现Android Studio有问题,在Android Studio的Logcat中日志怎么也不输出,这可能是Android Studio出问题了,此时可以考虑使用命令行的logcat命令来查看日志,但是logcat命令输出的日志很多,这就需要学一下如何对日志进行过滤了。
在Linux中过滤内容最简单的就是使用grep命令,比如要过滤包含ABCD字符串的日志,不论这个字符串是tag还是消息内容都是可以的:
假设有如下日志代码:
Log.i("ABCDEFG", "Hello")
Log.i("Hello","ABCDEFG")
过滤日志命令如下:
logcat | grep "ABCD"
输出结果如下:
09-23 16:49:00.900 3026 3026 I ABCDEFG : Hello
09-23 16:49:00.900 3026 3026 I Hello : ABCDEFG
grep过滤的是一行中所有的内容,所以我们按pid来过滤也是可以,比如上面的日志中的pid为3026,可以这样过滤:
logcat | grep "3026"
这样过滤时显示的日志就比较多,就像在AndroidStudio中显示的一样,因为程序一运行就会有许多的一些关于应用的默认的日志。
过滤包含字符A或字符B的日志:
logcat | grep -E "A|B"
-E表示使用扩展正则表达式,允许使用 | 作为逻辑 “或”。
过滤包含字符A同时还包含字符B的日志:
logcat | grep "A" | grep "B"
这个需求如果用正式表达式比较麻烦,并不是我们想的那样(logcat | grep -E "A&B"
),所以这里没用正则,而是先进行两次过滤,先过滤出包含A的,再从包含A的结果里面过滤出包含B的。
官方文档:
logcat命令行使用:https://developer.android.google.cn/tools/logcat?hl=zh_cn
logcat在AndroidStudio中使用:https://developer.android.google.cn/studio/debug/logcat?hl=zh-cn
通过如下命令可查看logcat命令使用帮助:
adb logcat --help
查看日志并对TAG进行过滤,比如要看TAG为MainActivity的日志:
adb logcat -s MainActivity
或者:
adb logcat MainActivity:D *:S
这里MainActivity为TAG,D表示过滤Debug或以上的日志,后面的 *:S
(大写S)不知道是什么意思,但是必须要加这个,不加的话过滤不起作用。
或者这样更简洁:
adb logcat *:S MainActivity
-s
其实就是 *:s
的等效方式。
保存日志到文件中:
adb logcat -s MainActivity > D:\Logcat\logcat.log
或者:
adb logcat -s MainActivity -f D:\Logcat\logcat.log
logcat会把之前缓冲的日志也输出,如果只想看最新的日志,可以先把缓冲中的日志先清空一下再输出:
adb logcat -c
过滤指定pid的日志:
先进入shell,然后:
logcat | grep $pid
或者:
logcat --pid=12394
或者直接在cmd命令行中:
adb logcat --pid=12394
把这里的pid替换为具体的值即可。当在命令行中我们不知道应用的pid是多少,则可以先使用TAG过滤出一个日志来,在这个日志上就有显示PID,然后再改为使用pid过虑即可,示例如下:
假如知道应用中有一个日志使用的TAG为ABCD,则过滤该日志为:
logcat -s ABCD
结果如下:
这里看到进程ID和线程ID是一样的,那我们开个子线程在,在子线程中输入日志,如下:
如上,由于在子线程中打印日志,线程ID和进程ID就不一样了,由此可见,主线程的线程ID和进程ID是一样的。
filterspecs
filterspecs
是一序列的:
<tag>[:priority]
所以这样的过滤规格是可以同时设置多个的,每个之间用空格分隔。<tag>
可以使用*
表示所有tag都要;优先级[:priority]
使用中括号括起来了,表示可有可无,比如,要过滤 tag 为 MainActivity:
logcat MainActivity
这里没有指定[:priority]
则默认为Verbose(最小的日志级别)
比如要过滤所有Error级别的日志,不论tag是什么:
logcat *:E
如要过滤 tag 为 MainActivity,且只要优先级为Warn级别的,则:
logcat MainActivity:W
同时过滤多个:
logcat MainActivity:W LoginActivity
这里LoginActivity没加日志级别,则默认为Verbose。
所有的日志级别如下:
- V Verbose (default for
<tag>
,比如:logcat MyTag
相当于:logcat MyTag:V
) - D Debug (default for
'*'
,比如:logcat *
相当于:logcat *:D
) - I Info
- W Warn
- E Error
- F Fatal
- S Silent (suppress all output)
在Android Studio中的日志级别只有V、D、I、W、E,这里还有F、S,其中F是严重错误,S是静默,它是级别最大的,使用这个级别则所有比它低的级别都不会输出,相当于所有的日志都被过滤掉了(即所有日志都不会被输出)。
如果没有 *
或-s
在命令行,则所有的filter默认为*:V
,所以如下的过滤会发现其实所有的日志都被输出了:
logcat LoginActivity:W
正确过滤如下:
logcat *:S LoginActivity:W
所以想表示只要看 tag 为 LoginActivity的日志:
logcat *:S LoginActivity
表示不想看LoginActivity的日志,其它的都要:
logcat LoginActivity:S
控制日志输出格式
除标记和优先级外,日志消息还包含许多元数据字段。您可以修改消息的输出格式,以便它们显示特定的元数据字段。为此,请使用 -v 选项,并指定下列某一受支持的输出格式:
- brief:显示优先级、标记以及发出消息的进程的 PID。
- long:显示所有元数据字段,并使用空白行分隔消息。
- process:仅显示 PID。
- raw:显示不包含其他元数据字段的原始日志消息。
- tag:仅显示优先级和标记。
- thread::旧版格式,显示优先级、PID 以及发出消息的线程的 TID。
- threadtime(默认值):显示日期、调用时间、优先级、标记、PID 以及发出消息的线程的 TID。
- time:显示日期、调用时间、优先级、标记以及发出消息的进程的 PID。
启动 logcat 时,您可以使用 -v 选项指定所需的输出格式:
[adb] logcat [-v <format>]
比如我们只想看日志内容,也不关心日志的时间进程ID等等的其它信息,则可以:
如上图,日志内容就只有日志消息,没有其它信息了。
各种格式效果如下: