RK3288 Android 6.0 logcat 过滤带冒号的 tag
logcat 过滤
logcat 过滤不打印的日志时,可以使用 <tag>:S
的参数,比如排除 ActivityManager 相关日志。使用 以下指令
logcat ActivityManager:S
但是我遇到一种特殊情况,应用app的tag中包含了冒号,比如 APP:SDK--
, 其它类似的tag有很多,这种情况使用以下指令是无法过滤掉的。
logcat APP:SDK--:S
为了分析原因,需要查看 logcat
源码。
system/core/logcat/logcat.cpp
system/core/liblog/logprint.c
logcat.cpp
logcat.cpp 中解析参数时,针对 s
使用 android_log_addFilterRule
解析。这里需要说明的是, logcat -s
与 logcat *:S
是等效的。logcat
在解析 <tag>:S
时也是调用 android_log_addFilterRule
函数。
for (;;) {
int ret;
ret = getopt(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:k");
if (ret < 0) {
break;
}
switch(ret) {
case 's':
// default to all silent
android_log_addFilterRule(g_logformat, "*:s");
break;
logprint.c
android_log_addFilterRule
定义于 logprint.c
文件。
int android_log_addFilterRule(AndroidLogFormat *p_format,
const char *filterExpression)
{
size_t tagNameLength;
android_LogPriority pri = ANDROID_LOG_DEFAULT;
tagNameLength = strcspn(filterExpression, ":");
if (tagNameLength == 0) {
goto error;
}
if(filterExpression[tagNameLength] == ':') {
pri = filterCharToPri(filterExpression[tagNameLength+1]);
if (pri == ANDROID_LOG_UNKNOWN) {
goto error;
}
}
if(0 == strncmp("*", filterExpression, tagNameLength)) {
/*
* This filter expression refers to the global filter
* The default level for this is DEBUG if the priority
* is unspecified
*/
if (pri == ANDROID_LOG_DEFAULT) {
pri = ANDROID_LOG_DEBUG;
}
p_format->global_pri = pri;
} else {
/*
* for filter expressions that don't refer to the global
* filter, the default is verbose if the priority is unspecified
*/
if (pri == ANDROID_LOG_DEFAULT) {
pri = ANDROID_LOG_VERBOSE;
}
char *tagName;
/*
* Presently HAVE_STRNDUP is never defined, so the second case is always taken
* Darwin doesn't have strnup, everything else does
*/
#ifdef HAVE_STRNDUP
tagName = strndup(filterExpression, tagNameLength);
#else
/* a few extra bytes copied... */
tagName = strdup(filterExpression);
tagName[tagNameLength] = '\0';
#endif /*HAVE_STRNDUP*/
FilterInfo *p_fi = filterinfo_new(tagName, pri);
free(tagName);
p_fi->p_next = p_format->filters;
p_format->filters = p_fi;
}
return 0;
error:
return -1;
}
分析以上代码发现,在处理 <tag>:S
或者 *:S
时,是通过分隔符 :
解析为前后两部分,当tag中出现冒号时是无法正确处理的。
为此,在保证原有功能不变的基础上,可以添加一些定制化的参数,新增新的api函数,用以支持过滤特定tag。
定制化logcat
logcat已经支持的参数列表为 :cdDLt:T:gG:sQf:r:n:v:b:BSpP:k
, 在这里添加一个没用到的参数,比如 C
.
--- a/core/logcat/logcat.cpp
+++ b/core/logcat/logcat.cpp
@@ -255,6 +255,7 @@ static void show_help(const char *cmd)
fprintf(stderr, "options include:\n"
" -s Set default filter to silent.\n"
" Like specifying filterspec '*:S'\n"
+ " -C Set customize filter to slient.\n"
" -f <filename> Log to file. Default is stdout\n"
" -r <kbytes> Rotate log every kbytes. Requires -f\n"
" -n <count> Sets max number of rotated logs to <count>, default 4\n"
@@ -492,7 +493,7 @@ int main(int argc, char **argv)
for (;;) {
int ret;
- ret = getopt(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:");
+ ret = getopt(argc, argv, ":cdDLt:T:gG:sQf:r:n:v:b:BSpP:C");
if (ret < 0) {
break;
@@ -504,6 +505,10 @@ int main(int argc, char **argv)
android_log_addFilterRule(g_logformat, "*:s");
break;
+ case 'C':
+ android_log_addFilterRule_custom(g_logformat);
+ break;
+
case 'c':
clearLog = 1;
mode |= ANDROID_LOG_WRONLY;
然后在 logprint.c
中添加定制化的代码。
+static int android_log_addFilterRule_customize(AndroidLogFormat *p_format,
+ const char *filterExpression)
+{
+ size_t tagNameLength;
+ android_LogPriority pri = ANDROID_LOG_SILENT;
+
+ tagNameLength = strlen(filterExpression);
+
+ char *tagName;
+
+#ifdef HAVE_STRNDUP
+ tagName = strndup(filterExpression, tagNameLength);
+#else
+ tagName = strdup(filterExpression);
+ tagName[tagNameLength] = '\0';
+#endif /*HAVE_STRNDUP*/
+
+ FilterInfo *p_fi = filterinfo_new(filterExpression, pri);
+ free(tagName);
+
+ p_fi->p_next = p_format->filters;
+ p_format->filters = p_fi;
+ return 0;
+}
+
+/**
+ * returns 0 on success and -1 on invalid expression
+ *
+ * Assumes single threaded execution
+ */
+
+int android_log_addFilterRule_custom(AndroidLogFormat *p_format)
+{
+ android_log_addFilterRule_customize(p_format, "APP:SDK--");
+ android_log_addFilterRule_customize(p_format, "APP:API--");
+ android_log_addFilterRule_customize(p_format, "APP:RUNTIME--");
+ return 0;
+}
这样一来就可以通过 logcat -C
去过滤特定标签信息了。
以上方法还可以进一步优化,比如添加打印等级相关的参数,针对当前业务已经够用,有兴趣的可以按需修改。
版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 litreily的博客!