Logcat 命令行工具

Logcat 是一种命令行工具,可以转储系统消息的日志,其中包括您使用 Log 类从应用写入的消息。

本页面介绍的是命令行 logcat 工具,但您也可以从 Android Studio 中的 Logcat 窗口查看日志消息。有关从 Android Studio 查看和过滤日志的信息,请参阅使用 Logcat 查看和写入日志

日志系统概述

Android 日志系统是一组由系统进程 logd 维护的结构化循环缓冲区。可用的缓冲区集合是固定的,并由系统定义。最相关的缓冲区有:

  • main:存储大多数应用日志。
  • system:存储源自 Android 操作系统的消息。
  • crash:存储崩溃日志。每个日志条目都有一个优先级、一个标识日志来源的标签以及实际的日志消息。

日志系统的主 C/C++ 接口是共享库 liblog 及其头文件 <android/log.h>。所有特定语言的日志功能(包括 android.util.Log)最终都会调用函数 __android_log_write。默认情况下,它调用函数 __android_log_logd_logger,该函数使用套接字将日志条目发送到 logd。从 API 级别 30 开始,可以通过调用 __android_set_log_writer 来更改日志功能。更多信息可在 NDK 文档中找到。

adb logcat 显示的日志会经过四级过滤:

编译时过滤
根据编译设置,某些日志可能会从二进制文件中完全移除。例如,可以将 ProGuard 配置为从 Java 代码中移除对 Log.d 的调用。
系统属性过滤
liblog 查询一组系统属性,以确定要发送到 logd 的最低严重级别。如果您的日志带有标签 MyApp,则会检查以下属性,这些属性应包含最低严重级别的首字母(VDIWE,或 S 以禁用所有日志):
  • log.tag.MyApp
  • persist.log.tag.MyApp
  • log.tag
  • persist.log.tag
应用过滤
如果未设置任何属性,liblog 会使用 __android_log_set_minimum_priority 设置的最低优先级。默认设置为 INFO
显示过滤
adb logcat 支持额外的过滤器,可以减少从 logd 显示的日志量。有关详细信息,请参阅过滤日志输出部分。

命令行语法

通过 adb shell 运行 logcat 的一般用法是:

[adb] shell logcat [<option>] ... [<filter-spec>] ...

也有 adb logcat 的简写形式,但这只是扩展为 adb shell logcat

选项

logcat 有很多选项。可用选项取决于您使用的设备的操作系统版本。要查看适用于您正在使用的设备的 logcat 帮助,请执行:

    adb logcat --help
    

请注意,由于 logcat 既是操作系统开发人员的工具,也是应用开发人员的工具(应用开发人员应使用 Android Studio),因此许多选项只能以 root 身份使用。

过滤日志输出

日志消息的标签是一个短字符串,表示消息源自的系统组件。例如,视图系统为“View”。

优先级是以下字符值之一,按从低到高排序:

    • V:详细 (最低优先级)
    • D:调试
    • I:信息
    • W:警告
    • E:错误
    • F:致命
    • S:静默 (最高优先级,不打印任何内容)
  • 要获取系统中使用的带优先级的标签列表,请运行 logcat 并观察每条消息的前两列,格式为 <priority>/<tag>

    以下是使用 logcat -v brief output 命令获取的简短 logcat 输出示例。输出显示消息与优先级级别“I”和标签“ActivityManager”相关:

    I/ActivityManager(  585): Starting activity: Intent { action=android.intent.action...}
    

    要将日志输出减少到可管理级别,请使用过滤器表达式限制日志输出。过滤器表达式允许您向系统指示您感兴趣的标签-优先级组合。系统会抑制指定标签的其他消息。

    过滤器表达式遵循此格式 tag:priority ...,其中 tag 表示感兴趣的标签,priority 表示该标签要报告的最低优先级级别。该标签达到或高于指定优先级的消息将写入日志。在单个过滤器表达式中提供任意数量的 tag:priority 规范。规范系列以空格分隔。

    以下是一个过滤器表达式示例,它会抑制所有日志消息,但“ActivityManager”标签优先级为“Info”或更高,以及“MyApp”标签优先级为“Debug”或更高的消息除外:

    adb logcat ActivityManager:I MyApp:D *:S
    

    前面表达式中的最后一个元素 *:S 将所有标签的优先级级别设置为“静默”,这确保只显示带有“ActivityManager”和“MyApp”的日志消息。使用 *:S 可确保日志输出仅限于您明确指定的过滤器。*:S 允许您的过滤器充当日志输出的允许列表。

    注意:在某些 shell 中,“*”字符由 shell 保留。如果您使用此类 shell,请将过滤器表达式用引号括起来:adb logcat "ActivityManager:I MyApp:D *:S"

    以下过滤器表达式显示所有标签上优先级级别为“warning”及更高的所有日志消息:

    adb logcat *:W
    

    如果您从开发计算机而不是在远程 adb shell 上运行 logcat,您还可以通过导出环境变量 ANDROID_LOG_TAGS 的值来设置默认过滤器表达式:

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

    如果您从远程 shell 运行 logcat 或使用 adb shell logcat,则 ANDROID_LOG_TAGS 过滤器不会导出到模拟器/设备实例。

    控制日志输出格式

    日志消息除了标签和优先级之外,还包含许多元数据字段。您可以修改消息的输出格式,以便它们显示特定的元数据字段。为此,请使用 -v 选项并指定以下支持的输出格式之一:

    • brief:显示优先级、标签和发出消息的进程的 PID。
    • long:显示所有元数据字段,并用空行分隔消息。
    • process:仅显示 PID。
    • raw:显示原始日志消息,不带其他元数据字段。
    • tag:仅显示优先级和标签。
    • thread: 一种旧版格式,显示发出消息的线程的优先级、PID 和 TID。
    • threadtime (默认):显示日期、调用时间、优先级、标签、PID 和发出消息的线程的 TID。
    • time:显示日期、调用时间、优先级、标签和发出消息的进程的 PID。

    启动 logcat 时,使用 -v 选项指定所需的输出格式:

    [adb] logcat [-v <format>]
    

    这是一个示例,展示了如何在 thread 输出格式中生成消息:

    adb logcat -v thread
    

    您只能使用 -v 选项指定一种输出格式。但是,您可以根据需要指定任意数量的修饰符,只要它们有意义即可。logcat 会忽略无意义的修饰符。

    格式修饰符

    格式修饰符会改变 logcat 输出。要指定格式修饰符,请使用 -v 选项,如下所示:

    adb logcat -b all -v color -d
    

    每个 Android 日志消息都关联着一个标签和优先级。您可以将任何格式修饰符与以下任何格式选项结合使用:

    • brief
    • long
    • process
    • raw
    • tag
    • thread
    • threadtime
    • time

    要格式化以下修饰符详细信息,请在命令行中输入 logcat -v --help

    • color:以不同颜色显示每个优先级级别。
    • descriptive:显示日志缓冲区事件描述。此修饰符仅影响事件日志缓冲区消息,对其他非二进制缓冲区没有影响。事件描述来自 event-log-tags 数据库。
    • epoch:以自 1970 年 1 月 1 日以来的秒数显示时间。
    • monotonic:以自上次启动以来的 CPU 秒数显示时间。
    • printable:确保所有二进制日志内容都已转义。
    • uid:如果访问控制允许,则显示已记录进程的 UID 或 Android ID。
    • usec:显示时间,精确到微秒。
    • UTC:以 UTC 时间显示时间。
    • year:在显示的时间中添加年份。
    • zone:在显示的时间中添加本地时区。

    查看备用日志缓冲区

    Android 日志系统为日志消息保留了多个循环缓冲区,并非所有日志消息都发送到默认循环缓冲区。要查看其他日志消息,请运行带 -b 选项的 logcat 命令,以请求查看备用循环缓冲区。您可以查看以下任何备用缓冲区:

    • radio:查看包含无线电/电话相关消息的缓冲区。
    • events:查看解释的二进制系统事件缓冲区消息。
    • main:查看主日志缓冲区(默认),其中不包含系统和崩溃日志消息。
    • system:查看系统日志缓冲区(默认)。
    • crash:查看崩溃日志缓冲区(默认)。
    • all:查看所有缓冲区。
    • default:报告 mainsystemcrash 缓冲区。

    -b 选项的用法是:

    [adb] logcat [-b <buffer>]
    

    以下是查看包含无线电和电话消息的日志缓冲区的示例:

    adb logcat -b radio
    

    要为要打印的所有缓冲区指定多个 -b 标志,请输入以下内容:

    logcat -b main -b radio -b events
    

    指定一个 -b 标志,其中包含以逗号分隔的缓冲区列表,例如:

    logcat -b main,radio,events
    

    从代码中记录

    Log 类允许您在代码中创建日志条目,这些条目会显示在 logcat 工具中。常见的日志方法包括:

    例如,使用以下调用:

    Kotlin

    Log.i("MyActivity", "MyClass.getView() — get item number $position")

    Java

    Log.i("MyActivity", "MyClass.getView() — get item number " + position);

    logcat 输出类似于以下内容:

    I/MyActivity( 1557): MyClass.getView() — get item number 1