chromium源码学习-调试日志 LOG

news/2024/4/17 7:57:10

在学习 chromium 源码时,我们经常需要增加调试日志,常见的用法一般是

// TurboNet.mm133134  LOG(INFO) << "TurboNet Engine started.";

在这里插入图片描述

其中 INFO 代表当前这条日志的级别,使用的时候就是输入 INFO 就行。接下来我们在探索下这个宏背后的内容。

一、基本用法

LOG 本身是一个宏:

#define LOG(severity) LAZY_STREAM(LOG_STREAM(severity), LOG_IS_ON(severity))

我们逐个解开:

1、LOG_STREAM

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

LOG_STREAM(severity) 会被转成具体 severity 对应的宏,例如 INFO 被转为宏 COMPACT_GOOGLE_LOG_INFO:

#define COMPACT_GOOGLE_LOG_INFO COMPACT_GOOGLE_LOG_EX_INFO(LogMessage)

宏 COMPACT_GOOGLE_LOG_EX_INFO:

#define COMPACT_GOOGLE_LOG_EX_INFO(ClassName, ...)                  \::logging::ClassName(__FILE__, __LINE__, ::logging::LOGGING_INFO, \##__VA_ARGS__)

ClassName 是 LogMessage,因此这里 COMPACT_GOOGLE_LOG_EX_INFO 代表的是 ::logging::LogMessage 类的构造方法,构造方法里调用 Init 方法初始化了一些调试信息比如文件名,行号,时间戳等,保存在 std::ostringstream 类型的成员变量 stream_ 中,LOG_STREAM 这个宏最终就是返回了这个 stream_对象。

2、LOG_IS_ON

#define LOG_IS_ON(severity)  (::logging::ShouldCreateLogMessage(::logging::LOGGING_##severity))
// severity 值如下
constexpr LogSeverity LOGGING_INFO = 0;
constexpr LogSeverity LOGGING_WARNING = 1;
constexpr LogSeverity LOGGING_ERROR = 2;
constexpr LogSeverity LOGGING_FATAL = 3;
constexpr LogSeverity LOGGING_DEBUG = 4;
constexpr LogSeverity LOGGING_NUM_SEVERITIES = 5;bool ShouldCreateLogMessage(int severity) {if (severity < g_min_log_level)return false;// Return true here unless we know ~LogMessage won't do anything.return g_logging_destination != LOG_NONE || g_log_message_handler ||severity >= kAlwaysPrintErrorLevel;
}// g_min_log_level
// 如果 SetMinLogLevel 未调用,g_min_log_level 默认为 LOGGING_FATAL
// 因此为了输出 LOGGING_INFO 级别的日志,需要将 g_min_log_level 的值设置为 <=-1 的值
void SetMinLogLevel(int level) {g_min_log_level = std::min(LOGGING_FATAL, level); 
}

3、LAZY_STREAM

#define LAZY_STREAM(stream, condition)  !(condition) ? (void) 0 : ::logging::LogMessageVoidify() & (stream)

如果 condition 为 false,则返回 nullptr,否则返回 stream 对象,这里 ::logging::LogMessageVoidify() 是一个空操作,该类内部重载了 & 运算符,对应一个空函数体,这么做是为了避免编译器警告 stream 未被使用。

二、进阶用法【未完待续】

VLOG、PLOG、DLOG

1、VLOG

整体跟 LOG 差不多,使用方式如下:

VLOG(1) << "Filter function already exists: " << filter_function<< " with associated data: " << user_data;
#define VLOG(verbose_level) \LAZY_STREAM(VLOG_STREAM(verbose_level), VLOG_IS_ON(verbose_level))// 除了对日志级别取负值,跟 LOG 一样,
#define VLOG_STREAM(verbose_level) \::logging::LogMessage(__FILE__, __LINE__, -(verbose_level)).stream()#define VLOG_IS_ON(verboselevel) \((verboselevel) <= ::logging::GetVlogLevel(__FILE__))
template <size_t N>
int GetVlogLevel(const char (&file)[N]) {return GetVlogLevelHelper(file, N);
}int GetVlogLevelHelper(const char* file, size_t N) {DCHECK_GT(N, 0U);// Note: |g_vlog_info| may change on a different thread during startup// (but will always be valid or nullptr).VlogInfo* vlog_info = g_vlog_info;return vlog_info ?vlog_info->GetVlogLevel(base::StringPiece(file, N - 1)) :GetVlogVerbosity();
}

三、日志输出

在 LogMessage::~LogMessage() 方法中,我们可以看到对各个系统平台的调试日志输出做了兼容,例如安卓(调用 __android_log_write)、iOS(调用__builtin_os_log_format)、Win(调用 OutputDebugStringA)等,因此鸿蒙的支持也需要在该方法中完成。
在这里插入图片描述

参考资料


https://www.xjx100.cn/news/3365574.html

相关文章

css预编译sass,css也可以变得优雅

1. 嵌套选择器 #content {article {h1 { color: #333 }p { margin-bottom: 1.4em }}aside { background-color: #EEE } }编译后 #content article h1 { color: #333 } #content article p { margin-bottom: 1.4em } #content aside { background-color: #EEE }2. 变量声明和使…

【Java+Springboot】----- 通过Idea快速创建SpringBoot项目操作方法

一、第一步&#xff1a; 点击选择【File】->【New】-> 【Project】 最后弹出[new Project]界面。 二、第二步&#xff1a; 1. 选择【Spring Initializr】 2. 然后选择【Project SDK】的版本 3. 然后 Choose Initializr Service URL 选择默认&#xff08;Default&#x…

自定义注解@Log 插入操作日志

一&#xff0c;注解描述 // 作用位置&#xff0c;参数 方法 Target({ElementType.PARAMETER, ElementType.METHOD}) // 作用范围 运行时 Retention(RetentionPolicy.RUNTIME) Documented public interface Log {/*** 模块*/public String title() default "";/*** 模…

搜维尔科技:借助 ARVR 的力量缩小现代制造业的技能差距

借助ARVR的力量缩小现代制造业的技能差距 搜维尔科技&#xff1a;Senseglove案例-扩展机器人技术及其VR应用

mybatis批量新增数据

数据量大的时候如果在循环中执行单条新增操作&#xff0c;是非常慢的。那么如何在mybatis中实现批量新增数据呢&#xff1f; 方法 insert 标签的 foreach 属性可以用于批量插入数据。您可以使用 foreach 属性遍历一个集合&#xff0c;并为集合中的每个元素生成一条插入语句。…

朵米3.5客服系统源码2023正式版

源码简介 朵米客服系统是一款全功能的客户服务解决方案&#xff0c;提供多渠道支持&#xff08;如在线聊天、邮件、电话等&#xff09;&#xff0c;帮助企业建立与客户的实时互动。该系统具有智能分流功能&#xff0c;可以快速将客户请求分配给适当的客服人员&#xff0c;提高…

tomcat 知多少

Tomcat的缺省端口&#xff1a; 默认端口为8080&#xff0c;可以通过在tomcat安装包conf目录下&#xff0c;service.xml中的Connector元素的port属性来修改端口。 tomcat 常见 Connector 运行模式(优化)&#xff1a; 这三种模式的不同之处如下&#xff1a; BIO &#xff1a; 一…

练气第六天

问:ANR怎么分析&#xff1f; ANR问题&#xff0c;这其实是一个非常综合性的问题&#xff0c;因为anr会涉及CPU负载&#xff0c;内存空间大小&#xff0c;线程锁&#xff0c;GC回收&#xff0c;这里面每个点&#xff0c;都是非常考验我们基本功的。 分析ANR问题&#xff0c;需…