Logcat使用

Logcat使用

参数

描述

-b

加载一个可使用的日志缓冲区供查看,比如event和radio。默认值是main

-c

清除缓冲区中的全部日志并退出(清除完后可以使用-g查看缓冲区)

-d

将缓冲区的log转存到屏幕中然后退出

-f

将log输出到指定的文件中<文件名>.默认为标准输出(stdout)

-g

打印日志缓冲区的大小并退出

-n

设置日志的最大数目,默认值是4,需要和-r选项一起使用

-r

时输出日志,默认值是16,需要和-f选项一起使用

-s

设置过滤器

-v

设置输出格式的日志消息。默认是短暂的格式。支持的格式列表

一般长时间输出log的话建议-f,-n,-r三个参数连用,这样当一个文件日志输出满了之后可以马上在另一个中进行输出

优先级语法

优先级使用字符标识,一下优先级从低到高

V –Verbose(最低优先级)

D – Debug

I – Info

W – Warning

E – Error

F – Fatal

S – Silent

为了减少不想要日志的输出,可以建立一个过滤器

过滤语法:tag:priority

//过滤TAG为ActivityManager输出级别大于I的日志与TAG为MyApp输出级别大于D的日志

adb logcat ActivityManager:I My App:D *:S

adb logcat *:W

设置过滤级别为W以上

如果用的比较多可以设置环境变量:

export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D*:S"

logcat源码分析

logat源码主要分布在:

system/core/logcat/logcat.cpp system/core/include/cutils/logger.h

使用了liblog库,编译出来的结果是可执行程序logcat。

我们从logcat.cpp的main函数开始分析。

主函数代码:

1 int main(int argc, char **argv)

2 {

3 ......

4

5 //1. 参数check和解析

6 g_logformat = android_log_format_new();

7

8 if (argc == 2 && 0 == strcmp(argv[1], "--test")) {

9 logprint_run_tests();

10 exit(0);

11 }

12

13 if (argc == 2 && 0 == strcmp(argv[1], "--help")) {

14 android::show_help(argv[0]);

15 exit(0);

16 }

17

18 // 参数的继续处理

19 for (;;) {

20 int ret;

21 ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:B");

22

23 if (ret < 0) {

24 break;

25 }

26

27 switch(ret) {

28 case 's':

29 // default to all silent

30 android_log_addFilterRule(g_logformat, "*:s");

31 break;

32

33 case 'c':

34 clearLog = 1;

35 mode = O_WRONLY;

36 break;

37 ......

38 }

39

40 //2. devices的过滤

41 if (!devices) {

42 devices = new log_device_t(strdup("/dev/"LOGGER_LOG_MAIN), false, 'm');

43 android::g_devCount = 1;

44 int accessmode =

45 (mode & O_RDONLY) ? R_OK : 0

46 | (mode & O_WRONLY) ? W_OK : 0;

47 // only add this if it's available

48 if (0 == access("/dev/"LOGGER_LOG_SYSTEM, accessmode)) {

49 devices->next = new log_device_t(strdup("/dev/"LOGGER_LOG_SYSTEM), false, 's');

50 android::g_devCount++;

51 }

52 }

53

54 //dev = devices;

55 while (dev) {

56 dev->fd = open(dev->device, mode);

57

58 ......

59

60 //3.读取一行

61 android::readLogLines(devices);

62 }

根据输入的参数,进行相应的分析和处理:

例如,输入--help,就调用

android::show_help(argv[0]);

//显示help信息。

然后进入for无限循环。在for循环中,进一步进行参数处理。包括getopt中的这些值。

ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:B");

函数用于过滤参数中是否包含cdt:gsQf:r::n:v:b:B中的值,并且返回这个值。

对于ret的处理就是switch case

对devices的分析:

devices的类型定义在logger.h中,如下:

#define LOGGER_LOG_MAIN "log/main"

#define LOGGER_LOG_RADIO "log/radio"

#define LOGGER_LOG_EVENTS "log/events"

#define LOGGER_LOG_SYSTEM "log/system"

可见,logcat -b后面的参数对应于文件系统中的某一个(几个)文件。

readLines函数的实现:

实现原理,实现一个无限循环,采用select多路复用,从

devices

中获取数据,这里的devices就是前面提到的

system, events , radio, main

多路复用select: 监听devices设备,超时时间设置为5ms。将结果通过read函数读取到内存中,即读取到queued_entry_t相关的内存中。

C 输出log到LogCat

1 #include

2 #include

3 #include

4 #include

5

6 #define LOG "c_log"

7 #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,LOG,__VA_ARGS__)

8 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG,__VA_ARGS__)

9 #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG,__VA_ARGS__)

10 #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG,__VA_ARGS__)

11 #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__)

12 #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG,__VA_ARGS__)

13

14 JNIEXPORT void JNICALL

15 Java_com_myc_jni_Jni_cLog(JNIEnv *env, jobject instance) {

16 LOGV("c输出测试: 等级v");

17 LOGD("c输出测试: 等级d");

18 LOGI("c输出测试: 等级i");

19 LOGW("c输出测试: 等级w");

20 LOGE("c输出测试: 等级e");

21 LOGF("c输出测试: 等级f");

22 }

View Code

相关推荐

怔 书法字典
byt365

怔 书法字典

10-03 👁️ 6012
欧路词典|英汉-汉英词典 slay是什么意思
365账号被限制什么原因

欧路词典|英汉-汉英词典 slay是什么意思

08-20 👁️ 797