2012年12月9日星期日

Filtering adb logcat output

Summary: This post shows several useful tips of viewing adb logcat output in shell command line.

When debugging, I usually find my screen be flooded by useless logs printed by someone else, and the logs that are useful to me are washed out at the same time. It really sucks. So I want to share some tips that I know for filtering the logs.

Please read Android official documentation Reading and Writing Logs first, which introduce the usage of the build-in filter of adb. It can filter logs by tags and by priority. If you prefer GUI, please refer to Using DDMS, which also provides the same filter.

An alternative way of filtering logcat output is using grep, which is the method that I want to share in the following paragragh.

1. White list

It's very easy to filter output by grep, and we can make use of the powerful regular expression matching function. An easy example is matching a string "MyApp" in any position of a log line:

adb logcat | grep MyApp
adb logcat | grep -i myapp #Ignore case
adb logcat | grep --color=auto -i  myapp #Set color of matching string. See grep help for more details.

We can match log tags in a line only. The default log output format looks like:

I/CacheService(  665): Preparing DiskCache for all thumbnails.

We can see a tag is the word starts from the third charater in a line, so the regular expression for matching tag "MyApp" is:

adb logcat | grep "^..MyApp"

We can also match a log priority. Log priority is the first charater of a line, so if we want to match tag "MyApp" of Error level, the expression is:

adb logcat | grep "^E.MyApp"

What about matching mutiple conditions? Simply use "|" to split all your expression. For example, if I want to match tag "MyApp" and "MyActivity", the command should be:

adb logcat | grep "^..MyApp\|^..MyActivity"
adb logcat | grep -E "^..MyApp|^..MyActivity"  #use egrep without backslash

2. Black list

Usage is almost the same, with a "-v" argumemt. For example, if I want to filter out the tag "MyApp" and "MyActivity", the command should be:

adb logcat | grep -v "^..MyApp\|^..MyActivity"
adb logcat | grep -vE "^..MyApp|^..MyActivity"  #use egrep without backslash

3. Show output of a process

Sometimes an app may contain several log tags, so if we match the whole process(in a same PID) we won't miss some important messages, because the exception thrown by Java usually share the same PID. We still use grep, first find out the pid of a package, then match the PID. The shell script is shown as below, the argument is the Java package name or command name like "com.android.media" or "system_server".

#!/bin/bash
packageName=$1
pid=`adb shell ps | grep $packageName | awk '{print $2}'`
adb logcat | grep --color=auto $pid

4. Show log from now on

Simply clear the logcat cache, maybe you also like to clear screen:

clear && adb logcat -c && adb logcat
clear; adb logcat -c; adb logcat

5. Process log files

Still use grep. If the log file is "myapp.log", and I only needs to see tag "MyApp" and "MyActivity" then output to "newmyapp.log" file, the command should be:

cat myapp.log | grep "^..MyApp\|^..MyActivity" > newmyapp.log

没有评论:

发表评论