Android Log的普遍问题


看过很多Android原生应用或者第三方应用的log记录都是相当的不规范,导致在控制台查看某个应用或者某个taglog输出是相当痛苦的事情。虽然你可以用grep命令来过滤指定的log,但是你记得住自己的应用有多少个log tag吗?本文就来谈谈如何通过简单的两步走,实现应用log的规范精致输出。

一种简单解决方案


Androidlog级别大部分都是D,少数是I/W/E或者V。于是,其实可以写个Logger的工具类,里面包含了应用所有用到的log tag,然后在其他需要log的类中声明私有静态字符串变量TAG时直接引用Logger中声明的log tag,这样在一个地方统一管理log tag,规范且不易疏漏和出错。Logger中的log tag包含统一的规则,比如你的应用是Calendar,那么你的log tag大致就可以写成:

1
2
3
public static final String TAG_TEST = "Cal:D:Test";
public static final String TAG_UI = "Cal:D:Ui";
public static final String TAG_MODEL = "Cal:D:Model";

而需要用到log的类中的TAG变量就可以直接引用以上log tag

1
private static final String TAG = Logger.TAG_UI;

于是,你在过滤你的应用log时就可以直接输入如下命令:

1
logcat-color | grep "Cal:[V|D]"

其中,logcat-coloradb logcat的替代命令——多彩颜色显示、可配置性高。

进一步小扩展


另外还有一个需要考虑的log问题是,有一些log在开发调试的时候可以极大方便地观测程序运行状态和定位程序问题,但是如果在对外的发布版本中如果也输出,一般是比较恼人的,而且如果log过于频繁,容易冲掉其他应用的log。大部分应用采用的解决方式是在代码中声明一个DEBUG开关,在开发的时候设置为true,在发布的时候重新设置为false。但是,有时候,你是会忘记这件事情的,而且更糟糕的是,当你关闭了开关之后,如果程序出现问题了,你还得重新安装打开了DEBUG开关的应用版本,然后才能重新抓取log,最后根据log定位问题。

其实,可以通过adb命令来动态开关log tag,需要的时候开启就能输出指定的log,默认是关闭的:

1
2
adb shell setprop log.tag.Cal:V VERBOSE
adb shell setprop log.tag.Cal:V ASSERT

其中,第一个命令是将Cal:Vlog tag开启,第二个命令是将其关闭(因为一般不会用到ASSERT级别的log,所以就相当于关闭了)。

因此,我们可以将需要动态开关的log tag都声明为Cal:V开头的,然后在输出log之前进行判断:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static final String TAG_VERBOSE = "Cal:V";
private static boolean isLoggable(String tag) {
if (tag.contains(TAG_VERBOSE)) {
return Log.isLoggable(TAG_VERBOSE, Log.VERBOSE);
} else {
return true;
}
}
public static void d(String tag, String msg) {
if (isLoggable(tag)) {
android.util.Log.d(tag, msg);
}
}

美好Log生活

现在,只要遵循log前缀规则还有log开关判断,就可以动态开关并输出精美的应用log了,生活顿时美好了许多。

留言

2014 6月 12