以前写过一篇在android中添加log的文章,写那篇文章时是在调webkit的js代码时遇到用系统的LOGD等函数无法打印出log信息,于是自己写了个log函数,来打印js信息,
这次写的log可以实现不同级别的log打印不同的颜色,可以定位到log信息所在的函数 和所在的行数,系统的LOGD等函数需要自己定义个TAG来确定是那个模块的log,我将其优化了一下,不用自己定义TAG,直接以文件名作为log的模块名,这样在看不同错误时察看log就很方便了,系统的所有log都是白颜色的,如果是错误的log,需要细细的找,我将错误的log信息设置为红颜色,这样看到红颜色的log就表示代码中有错误发生,很方便,前一篇我写的是java中的log,都是遵循这个规律。
下面是log的实现:
首先定义log的宏。
#define YVERBOSE 2
#define YDEBUG 3
#define YINFO 4
#define YWARN 5
#define YERROR 6
#define YULOGV(fmt, ...) DLOG(YVERBOSE, "%s %s (line: %d) " fmt"\033[0m ", __FILE__,__FUNCTION__,__LINE__, ##__VA_ARGS__)
#define YULOGD(fmt, ...) DLOG(YDEBUG, "%s %s (line: %d) " fmt"\033[0m ", __FILE__,__FUNCTION__,__LINE__, ##__VA_ARGS__)
#define YULOGI(fmt, ...) DLOG(YINFO, "%s %s (line: %d) " fmt"\033[0m ", __FILE__,__FUNCTION__,__LINE__, ##__VA_ARGS__)
#define YULOGW(fmt, ...) DLOG(YWARN, "%s %s (line: %d) " fmt"\033[0m ", __FILE__,__FUNCTION__,__LINE__, ##__VA_ARGS__)
#define YULOGE(fmt, ...) DLOG(YERROR, "%s %s (line: %d) " fmt"\033[0m ", __FILE__,__FUNCTION__,__LINE__, ##__VA_ARGS__)
YVERBOSE
YDEBUG
YINFO
YWARN
YERROR
这几个宏的值是系统固定的,这样在打印log信息时不同的级别的log在一行的最开始会打印这个log级别的标志,如YDEBUG这个宏在打印log信息时,一行的最开始是用
D/来表示的。
DLOG函数的实现:
int DLOG(int prio, const char *fmt, ...)
{
char *colorv = "\033[0;37m";
char *colord = "\033[0;34m";
char *colori = "\033[0;32m";
char *colorw = "\033[0;33m";
char *colore = "\033[0;31m";
int len = strlen(colord);
va_list ap;
char buf[1024] = {0};
char tmp[1024] = {0};
int i = 0;
int j = 0;
int k = 0;
int p = 0;
int d = 0;
char *fp =fmt;
va_start(ap,fp);
vsnprintf(buf, 1024, fmt, ap);
va_end(ap);
for (i = 0; i < 1024; i++) { //去掉换行符\n
if(buf[i] == '\n') {
buf[i] = ' ';
}
}
p = i;
for(i =0; i<p; i++) {//确定文件名长度
if(buf[i] == ' ') {
d = i;
break;
}
}
for (i = d ; i >=0; i--) { //
if(buf[i] != '/' || buf[i] != ' ') {//确定最后文件名长度
k++;
}else {
break;
}
}
//我在打印文件名时,打印的是文件名的绝对路径,不只是文件名,包括了文件所在的路径,所以需要两次确定文件名长度。
switch (prio) {//设置不同级别的log的颜色值
case 2:
strncpy(tmp,colorv,len);
break;
case 3:
strncpy(tmp,colord,len);
break;
case 4:
strncpy(tmp,colori,len);
break;
case 5:
strncpy(tmp,colorw,len);
break;
case 6:
strncpy(tmp,colore,len);
break;
default:
break;
}
for (i = d - k + 1 ,j = len; i <= d; i++,j++) { //获取文件名,将文件名作为tag使用,
tmp[j] = buf[i];
}
tmp[j] = '\0';
return __android_log_write(prio, tmp, &buf[d+1]);
}
可以将上面的宏加到系统的cutils/log.h文件里,将函数的实现放到liblog/logd_write.c 文件里,这样就能当系统的log使用了,在所有的c c++代码中直接include<cutils/log.h>就能使用自己定义的log了。
打印的log截图: