chromium源码学习-调试日志 LOG

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

LOG(INFO) << "调试信息";

其中 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)等,因此鸿蒙的支持也需要在该方法中完成。
在这里插入图片描述

参考资料

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/788807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读所罗门的密码笔记08_共生思想(下)

1. 机器判断 1.1. 在生活的各个领域&#xff0c;机器正在我们无意识的情况下做出更多的决定 1.1.1. 我们看到的新闻会塑造我们的观点和行动&#xff0c;它们是根据我们过去行为中所表达的倾向&#xff0c;或者其他同类人的行为而生成的 1.2. …

K-均值聚类算法

K-均值聚类算法是一种常用的无监督学习算法&#xff0c;用于将数据集分成 K 个簇。该算法的主要思想是通过迭代的方式将数据点分配到离它们最近的簇中&#xff0c;并更新簇的中心点&#xff0c;直到满足某个停止条件为止。 以下是 K-均值聚类算法的基本步骤&#xff1a; 初始化…

【热门话题】WebKit架构简介

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 WebKit架构简介一、引言二、WebKit概览1. 起源与发展2. 模块化设计 三、WebCore…

软考高级架构师:流水线的概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

基于SSM的“任务发布接收平台”的设计与实现(源码+数据库+文档+PPT)

基于SSM的“任务发布接收平台”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SSM 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 登录界面 前台界面 收藏界面 留言管理界面 任务管理界面 订…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑灵活性供需平衡的新型电力系统长短期储能联合规划》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

file_get_contents(‘php://input‘); 这个postman要如何传参

在 Postman 中传递参数给 file_get_contents(php://input); 是通过请求的 Body 部分来实现的。使用 Postman 进行 API 接口测试时&#xff0c;可以按照以下步骤来传递参数&#xff1a; 打开 Postman 并创建一个新的请求。在请求的 URL 地址栏输入你的 API 地址。选择请求方法为…

蓝桥杯刷题day13——自助餐【算法赛】

一、问题描述 食堂最近推出了自助取餐功能&#xff0c;可以通过盘子的形状自动计算费用。你参与到自助计算价格的项目工作中。视觉组的同学已经帮你通过图像识别把盘子图片转换为了字符串&#xff0c;你只需要计算具体的价格即可。 餐盘的费用如下表所示: 你将会得到n 个字符…

Spark实战:词频统计

文章目录 一、Spark实战&#xff1a;词频统计&#xff08;一&#xff09;Scala版1、分步完成词频统计2、一步搞定词频统计 &#xff08;二&#xff09;Python版1、分步完成词频统计2、一步搞定词频统计 二、实战总结 一、Spark实战&#xff1a;词频统计 &#xff08;一&#x…

顶顶通呼叫中心中间件-话术编辑器机器人转人工坐席配置(mod_cti基于FreeSWITCH)

顶顶通呼叫中心中间件-话术编辑器机器人转人工座席配置(mod_cti基于FreeSWITCH) 配置方法 一、ACD排队转接 二、伴随转接 比如你设置的通知规则是任意满足一个就通知那么通话时间设置为10 秒那样他只要通话时间到10秒他就会转坐席。 如果要转人工的时侯转手机可以这样配置 把…

CSS网页布局权威指南02 样式表内容

02 Stylesheet Contents CSS网页布局权威指南02 样式表内容 Inside a stylesheet, you’ll find a number of rules that look a little something like this: 在样式表中&#xff0c;你会发现许多规则看起来有点像这样: h1 {color: maroon;} body {background: yellow;}St…

【25考研】:四川大学计算机学院24届874考研考情分析

去年的考情分析也是我做的&#xff0c; 今年就在去年的基础上做了。保持形式不变&#xff0c;更改数据。 21考情&#xff1a; 万载月寒肠断客&#xff1a;四川大学计算机学院21届CS考研考情分析 22考情&#xff1a; 懒羊羊&#xff1a;四川大学计算机学院2022考研考情分析 2…

AI 论道|极狐GitLab 客户私享会上海站成功举办

3 月 22 日下午&#xff0c;极狐GitLab 在上海办公室举办了客户私享会&#xff0c;邀请了来自多个行业的多家客户&#xff0c;围绕 AI 提升研发效率的道法术器进行了充分交流。整个交流时长达两个多小时。 极狐GitLab 战略业务与区域发展副总裁何庆出席了此次活动并致开场辞。他…

图论做题笔记:dfs

Leetcode - 797&#xff1a;所有可能的路径 题目&#xff1a; 给你一个有 n 个节点的 有向无环图&#xff08;DAG&#xff09;&#xff0c;请你找出所有从节点 0 到节点 n-1 的路径并输出&#xff08;不要求按特定顺序&#xff09; graph[i] 是一个从节点 i 可以访问的所有节…

【Python面试题收录】Python的可变对象与不可变对象

一、可变对象与不可变对象的定义 在Python中&#xff0c;对象的可变性是指对象的内部状态&#xff08;值&#xff09;是否允许在对象创建后发生改变。根据这一特性&#xff0c;Python的数据类型可以分为两大类&#xff1a;可变对象&#xff08;mutable objects&#xff09;和不…

数据结构——红黑树详解

一、红黑树的定义 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出两倍&#xff0c…

基于Docker for Windows部署ChatGPT-Next-Web

基于Docker for Windows部署ChatGPT-Next-Web 项目地址安装Docker for Windows部署项目参数讲解参数示例 运行 项目地址 https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web 安装Docker for Windows 官网地址&#xff1a;https://www.docker.com/ 下拉找到Download 选择W…

Java设计模式:代理模式的静态和动态之分(八)

码到三十五 &#xff1a; 个人主页 心中有诗画&#xff0c;指尖舞代码&#xff0c;目光览世界&#xff0c;步履越千山&#xff0c;人间尽值得 ! 在软件设计中&#xff0c;代理模式是一种常用的设计模式&#xff0c;它为我们提供了一种方式来控制对原始对象的访问。在Java中&a…

文件操作的详序

1.为什么使用文件&#xff1f; 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存中&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就丢失了&#xff0c;等再次运行程序&#xff0c;是看不到程序的数据的&#xff0c;如果将数据进行持久化的保存…

Linux 使用管理线程、多线程、分离线程

目录 一、使用线程 1、pthread_create创建线程 2、pthread_join等待线程 主线程获取新线程退出结果 获取新线程退出返回的数组 3、线程异常导致进程终止 4、pthread_exit 5、pthread_cancel 6、主线程可以取消新线程&#xff0c;新线程可以取消主线程吗 二、如何管理线…