Log等级
Android log
等级在android/log.h
中定义如下:
typedef enum android_LogPriority {
/** For internal use only. */
ANDROID_LOG_UNKNOWN = 0,
/** The default priority, for internal use only. */
ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */
/** Verbose logging. Should typically be disabled for a release apk. */
ANDROID_LOG_VERBOSE,
/** Debug logging. Should typically be disabled for a release apk. */
ANDROID_LOG_DEBUG,
/** Informational logging. Should typically be disabled for a release apk. */
ANDROID_LOG_INFO,
/** Warning logging. For use with recoverable failures. */
ANDROID_LOG_WARN,
/** Error logging. For use with unrecoverable failures. */
ANDROID_LOG_ERROR,
/** Fatal logging. For use when aborting. */
ANDROID_LOG_FATAL,
/** For internal use only. */
ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */
} android_LogPriority;
缓冲池
Android的日志系统包含了一系列回环缓冲池,这些缓冲池由系统进程logd
来维护。
其中main
缓冲池存储大部分应用日志;system
缓冲池存储Android系统的日志;crash
存储崩溃日志,等等。
typedef enum log_id {
LOG_ID_MIN = 0,
/** The main log buffer. This is the only log buffer available to apps. */
LOG_ID_MAIN = 0,
/** The radio log buffer. */
LOG_ID_RADIO = 1,
/** The event log buffer. */
LOG_ID_EVENTS = 2,
/** The system log buffer. */
LOG_ID_SYSTEM = 3,
/** The crash log buffer. */
LOG_ID_CRASH = 4,
/** The statistics log buffer. */
LOG_ID_STATS = 5,
/** The security log buffer. */
LOG_ID_SECURITY = 6,
/** The kernel log buffer. */
LOG_ID_KERNEL = 7,
LOG_ID_MAX,
/** Let the logging function choose the best log target. */
LOG_ID_DEFAULT = 0x7FFFFFFF
} log_id_t;
接口
系统提供liblog
共享库和<android/log.h>
头文件来访问日志系统。
所有的日志事件最终都会调用到__android_log_write
方法;这个方法使用__android_log_logd_logger
方法通过socket
将日志写入logd
。
Android API level 30
开始可以使用__android_log_set_logger
来更改日志方法。
过滤
Android日志有四层过滤:
- 编译时过滤:譬如使用
proguard
移除掉所有Log.d
的调用 - 系统属性过滤:
liblog
通过读取一些系统属性,来决定发送给logd
的log的最小敏感级别,譬如tag
为MyApp
的log,会检查以下属性(log级别用单字符字母V
、D
、I
、W
、E
代表,S
代表关闭所有log)
*.log.tag.MyApp
*.persist.log.tag.MyApp
*.log.tag
*.persist.log.tag
- 应用过滤:如果上述属性都没有设置,则
liblog
使用通过__android_log_set_minimum_priority
设置的最小优先级,默认值为INFO
adb logcat
可以过滤logd
中的log。
logcat
命令
logcat
命令行语法如下:
[adb] logcat [<option>] ... [<filter-spec>] ...
可以通过adb
直接运行logcat
:
$ adb logcat
也可以通过adb shell
创建到设备的连接,然后执行logcat
:
$ adb shell
# logcat
logcat --help
使用logcat --help
命令可用查看所有选项
$ adb logcat --help
Usage: logcat [options] [filterspecs]
General options:
-b, --buffer=<buffer> Request alternate ring buffer(s):
...
也可以查看选项的详细信息:
$ adb logcat -v --help
过滤日志输出
通过tag:priority ...
方式设置过滤表达式。
tag
标签可以使用*
以匹配所有标签
优先级priority
有:
V
: VerboseD
: DebugI
: InfoW
: WarningE
: ErrorF
: FatalS
: Silent
priority
可以忽略,默认D
譬如:
adb logcat ActivityManager:I MyApp:D *:S
只显示标签为ActivityManager
的优先级为I
及以上的日志及标签为MyApp
的优先级为D
以上的日志,其它日志都忽略
还可以使用ANDROID_LOG_TAGS
环境变量来设置过滤表达式
$ adb shell
# export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S"
# logcat
输出格式
使用logcat -v
选项可以设置日志输出格式。
-v, --format=<format>
有以下几种格式:
brief
:显示优先级、标签、PID及消息long
:显示日志所有元数据信息,消息之间使用空行分隔process
:只显示优先级、进程PID及消息raw
:只显示原始日志消息tag
:只显示优先级、标签与消息thread
:显示优先级、PID、TID及消息threadtime
:默认格式,显示日期、时间、优先级、标签、PID、TID及消息time
:显示日期、时间、优先级、标签、PID及消息
默认格式为threadtime
譬如:
$ adb logcat -v brief
修饰符
可以使用如下修饰符(或其组合)来修改输出样式:
color
:不同优先级的日志使用不同的颜色进行显示descriptive
:Show log buffer event descriptions. This modifier affects event log buffer messages only, and has no effect on the other non-binary buffers. The event descriptions come from the event-log-tags database.epoch
:时间显示为从1970/1/1
开始的秒数monotonic
:时间显示为最近启动时间开始的秒数printable
: Ensure that any binary logging content is escaped.uid
:显示发送日志的进程的UID
或Android ID
usec
:时间精度显示到微秒UTC
:显示UTC
时间year
:显示时间加入年份zone
:显示时间加入时区
譬如:
$ adb logcat -v color,brief
不同优先级日志显示不同颜色,同时显示格式为brief
切换日志缓冲区
logcat
默认显示main
、system
、crash
缓冲区内容,可以使用-b
切换缓冲区:
-b, --buffer=<buffer>
可用<buffer>
如下:
radio
:显示radio/telephony
相关日志events
:显示解析的系统事件消息main
:显示主日志system
:显示系统日志crash
:显示崩溃日志all
:显示所有日志缓冲区default
:显示默认的main
、system
、crash
缓冲区日志
示例:
adb logcat -b radio
adb logcat -b main -b radio -b events
adb logcat -b main,radio,events
选项(options)
其它选项如下:
选项 | 描述 |
---|---|
-c, --clear | 清理选定的缓冲区并退出。默认的缓冲区集合为main 、system 、crash。可以使用 -b all -c`清理所有缓冲区 |
-e <expr>, --regex=<expr> | 只打印匹配正则表达式<expr> 的日志 |
-m <count>, --max-count=<count> | 打印<count> 数量的日志并退出。可以配合--regex 使用,也可以单独使用 |
配合--regex 及--max-count 使用 | |
-d | dump日志到屏幕上并退出 |
-f <filename> | 输入日志到<filename> ,默认为stdout |
-g, --buffer-size | 打印指定log缓冲区的大小 |
-n <count> | 需要配合-r 选项使用,设置环绕日志数量为<count> ,默认为4 |
-r <kbytes> | 需要配合-f 选项使用,设置环绕输出文件大小,以k字节 为单位,默认为16 |
-s | 等同于*:S 正则表达式,设置所有tag的优先级为静默,通常在添加内容的过滤表达式前,配合过滤表达式达到只显示指定内容的功能 |
-D,--dividers | 每个log缓冲区之间显示分隔线 |
-c | 清理所有log并退出 |
-t <count> | 只打印最近的<count> 行日志,包含了-d 的功能 |
-t ' | 只打印从指定时间<time> 开始的日志,包含-d 的功能,例:adb logcat -t '01-26 20:52:41.820' |
-T <count> | 类似-t <count> ,不包含-d 功能 |
-T ' | 类似-t '<time>' ,不包含-d 功能 |
-L, --last | dump上次重启之前的log |
-B, --binary | 二进制形式输出log |
-S, --statistics | 输出中包含统计信息 |
-G <size> | 设置log回绕缓冲区大小,可以在<size> 尾部添加K 或M |
-p, --prune | 打印当前黑名单白名单 |
-P '<list> ...' | |
--prune '<list> ...' -P '<white_and_black_list>' | 设置黑/白名单。白名单用<white> 黑名单用~<black> 。其中<white> 和<black> 可以用UID 、UID/PID 、/PID 来表示。 |
--pid=<pid> ... | 只打印指定进程的日志 |
--wrap | Sleep for 2 hours or when the buffer is about to wrap whichever comes first. Improves efficiency of polling by providing an about-to-wrap wakeup. |