Chromium源码阅读(10):了解Log模块

Chromium许多日志被TraceEvent代替了,因此TraceEvent出现的频率要比Log高很多。
但是也有不少场景使用Log。
在blink,Log的实现由blink/base提供,而chromium的日志由blink/render/core/base/logging.h提供。一些底层的日志由absel的log模块提供。
说实话,日志模块的实现数量有点多。这些实现在使用时都是使用Stream的形式打印日志,使用形式大同小异。

日志系统的设计细节

错误对话框处理

  • 错误消息显示: 当应用程序遇到断言失败或致命错误时,默认情况下会弹出一个对话框展示错误信息。然而,这个UI的创建会导致消息循环,这可能使应用在不好的状态中处理或分发消息到现有窗口,导致挂起或异常行为。
  • 分离进程显示错误: 为了避免上述问题,可以在与主应用程序相同的目录下创建一个名为DebugMessage.exe的独立程序,用于专门显示致命错误对话框。这样即使主程序处于不稳定状态,错误信息也能正确显示而不影响主程序的其他部分。
  • 简化命令行解析: 此独立程序接收错误信息作为命令行参数,不会包含应用程序名称,以便于解析。

日志宏

  • 基本日志: 提供了一系列宏,如LOG(INFO),用于在不同严重级别下记录日志信息。
  • 条件日志: 可以使用LOG_IF(INFO, condition)根据条件记录日志。
  • 断言宏: CHECK(condition)在所有构建模式下都有效,如果条件不满足,则记录FATAL级别的日志并终止程序。

调试模式日志

  • 调试宏: DLOG(INFO)仅在调试模式下生效,而在非调试模式下会被编译器忽略。
  • 调试断言: DLOG_ASSERT(condition)在调试模式下工作,类似于CHECK

详细日志

  • 详细级别日志: VLOG(1)允许根据不同的详细级别记录日志,可以通过运行参数--v=<level>开启。
  • 模块特定日志: 可以指定特定模块的详细级别,例如--vmodule=profile=2
  • 通配符支持: 模块名可以使用通配符*?匹配多个文件或目录下的源文件。

其他特性

  • 系统错误日志: PLOG(ERROR)附加系统错误信息到日志中。
  • 特殊日志级别: DFATALDCHECK启用的构建中等同于FATAL,在普通构建中为ERROR
  • 格式化输出: 日志输出包括PID、TID、日期时间、日志级别、文件名及行号等信息。

配置和偏好设置

  • 用户可以通过SetLogItems()函数调整日志的可见性。
  • 在Chrome OS上,日志输出可以切换到syslog-like格式。

LOG_STREAM

在实际打印日志的时候,是以流式打印的,例如:

LOG(INFO) << "Found " << num_cookies << " cookies";

LOG宏定义如下:


// We use the preprocessor's merging operator, "##", so that, e.g.,
// LOG(INFO) becomes the token COMPACT_GOOGLE_LOG_INFO.  There's some funny
// subtle difference between ostream member streaming functions (e.g.,
// ostream::operator<<(int) and ostream non-member streaming functions
// (e.g., ::operator<<(ostream&, string&): it turns out that it's
// impossible to stream something like a string directly to an unnamed
// ostream. We employ a neat hack by calling the stream() member
// function of LogMessage which seems to avoid the problem.
#define LOG_STREAM(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()

#define LOG(severity) LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))
#define LOG_IF(severity, condition) \
  LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity) && (condition))

// The VLOG macros log with negative verbosities.
#define VLOG_STREAM(verbose_level) \
  ::logging::LogMessage(__FILE__, __LINE__, -(verbose_level)).stream()

这段代码的解读如下:

  1. LOG_STREAM 宏:

    #define LOG_STREAM(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
    

    这个宏接受一个参数severity,它是一个日志级别(例如,INFO、ERROR等)。宏中的##是C++预处理器的字符串拼接操作符,它会将两个独立的标识符拼接成一个新的标识符。因此,LOG_STREAM(severity)被展开为COMPACT_GOOGLE_LOG_severity.stream()

  2. LOG 和 LOG_IF 宏:

    #define LOG(severity) LAZY_STREAM(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值