chromium源码学习-调试日志 LOG

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

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

参考资料

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网易云歌曲评论抓取

网易云歌曲评论爬取 步骤1.找到一首歌曲2.按下F12键打开开发者模式,对其进行抓包3.查找获得评论数据的接口4.对获得评论数据接口进行分析5.构建加密函数方法一方法二运行结果全部代码使用Js文件只使用python新的代码小结与展望这次的任务是获取网易云音乐下面的评论,涉及的知…

AI绘图:Stable Diffusion WEB UI 详细操作介绍:进阶-面部修复和调参

结合两篇文章完成了本地部署和基础操作,现在我们来介绍下进阶内容:面部修复,高清修复和调参区。 一:脸部修复 面部修复的适用在画真人、三次元的场景,特别是在画全身的时候 一般在画全身,由于脸部占比的空间比较小,那么绘制出来的效果就会比较差 1.面部修复 SD 支持…

C++核心编程——4.2(2)对象的初始化和清理

4.2.5 深拷贝与浅拷贝 浅拷贝&#xff1a;编译器提供的简单的赋值拷贝操作 深拷贝&#xff1a;在堆区重新申请空间&#xff0c;进行拷贝操作 示例&#xff1a; class Person { public://无参&#xff08;默认&#xff09;构造函数Person() {cout << "无参构造函数…

【复现】飞鱼星上网行为管理系统RCE漏洞_67

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 飞鱼星企业级智能上网行为管理系统是成都飞鱼星科技开发有限公司开发的一款上网行为管理路由器&#xff0c;专为中小企业、政府机…

Unity之PUN实现多人联机射击游戏的优化(Section 2)

目录 &#x1f3ae;一、准备工作 &#x1f3ae;二、实现手雷投掷动作 &#x1f3ae;三、手雷投掷同步 &#x1f4a4;3.1 photonView.RPC &#x1f3ae;四、同步手雷伤害 这几周都给我布置任务了&#xff0c;最近可忙。现在终于有机会更新了&#xff0c;也谢谢大家的阅读&a…

flink1.18源码编译后standalone模式-master启动

1、编译成功后 2、准备运行环境 • 在项⽬根⽬录下&#xff0c;创建如下两个⽂件夹&#xff1a; • 找到如下⼦模块&#xff0c;并展开如图 • 将上图中conf下的⽂件&#xff0c;拷⻉到项⽬根⽬录下创建的conf下 • 将上图中的lib下的jar包&#xff0c;拷⻉到项⽬根⽬录下…

Android JNI 调用第三方SO

最近一个项目使用了Go 编译了一个so库&#xff0c;但是这个so里面还需要使用第三方so库pdfium, 首先在Android工程把2个so库都放好 在jni中只能使用dlopen方式&#xff0c;其他的使用函数指针的方式来调用&#xff0c;和windows dll类似&#xff0c;不然虽然编译过了但是会崩溃…

STL是什么?如何理解STL?

文章目录 1. 什么是STL2. STL的版本3. STL的六大组件4. 如何学习STL5.STL的缺陷 1. 什么是STL STL(standard template libaray-标准模板库)&#xff1a;是C标准库的重要组成部分&#xff0c;不仅是一个可复用的组件库&#xff0c;而且是一个包罗数据结构与算法的软件框架。 2. …

JVM高级篇之GC

文章目录 版权声明垃圾回收器的技术演进ShenandoahShenandoah GC体验Shenandoah GC循环过程 ZGCZGC简介ZGC的版本更迭ZGC体验&使用ZGC的参数设置ZGC的调优 版权声明 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明&#xff0c;所有版权属于黑马…

ESP32学习---ESP-NOW(一)

ESP32学习---ESP-NOW&#xff08;一&#xff09; 官网简介arduino 官网简介 首先看官网的介绍&#xff1a;https://www.espressif.com.cn/zh-hans/solutions/low-power-solutions/esp-now ESP-NOW 是乐鑫定义的一种无线通信协议&#xff0c;能够在无路由器的情况下直接、快速…

Pycharm显示Low memory的解决办法

这种情况该怎么办呢&#xff1f; 按照网上的说法&#xff0c;首先按照下图&#xff0c;选择memory Indicator: 就可以在pycharm的右下角看到内存以及其分配情况&#xff08;allocated表示被分配的&#xff0c;可以看到我的已经被分配完了&#xff0c;应该是这个意思&#xff0…

FPGA高端项目:解码索尼IMX327 MIPI相机+2路视频融合叠加,提供开发板+工程源码+技术支持

目录 1、前言2、相关方案推荐本博主所有FPGA工程项目-->汇总目录我这里已有的 MIPI 编解码方案 3、本 MIPI CSI-RX IP 介绍4、个人 FPGA高端图像处理开发板简介5、详细设计方案设计原理框图IMX327 及其配置MIPI CSI RX图像 ISP 处理HLS多路视频融合叠加图像缓存HDMI输出工程…

基于vscode Arduino插件开发Arduino项目

基于vscode Arduino插件开发arduino项目 插件配置问题记录1. 指定编译输出文件夹2. 编译下载时不输出详细信息3. 输出端口信息乱码4. 通过串口输出中文&#xff0c;vscode对应的串口助手上会显示乱码&#xff08;未解决&#xff09; 插件配置 环境&#xff1a;Arduino插件版本…

Linux基础篇:VMware centos7虚拟机网络配置——桥接模式

VMware centos7虚拟机网络配置——桥接模式 1 搞清楚什么是桥接模式 桥接模式允许虚拟机直接连接到物理网络&#xff0c;就像它是物理网络中的一个独立设备一样。在这种模式下&#xff0c;虚拟机将具有与宿主机相同网络中的其他设备相同的网络访问权限。虚拟机将获得一个独立…

机器学习——几个线性模型的简介

目录 形式 假设 一元回归例子理解最小二乘法 多元回归 广义线性回归 对数线性回归 逻辑回归 线性判别分析 形式 线性说白了就是初中的一次函数的一种应用&#xff0c;根据不同的(x,y)拟合出一条直线以预测&#xff0c;从而解决各种分类或回归问题&#xff0c;假设有 n …

Spring-IoC 基于xml管理

现大多使用注解方式&#xff0c;xml方式并不简洁&#xff0c;本文仅记录xml用作基础学习。 0、前提 首先在父项目的pom.xml中配置好依赖们。然后子模块也可以使用这些依赖。 在resource目录下创建Spring的xml文件&#xff0c;名称无要求&#xff0c;本文使用bean.xml。文件最…

大数据实验统计-1、Hadoop安装及使用;2、HDFS编程实践;3、HBase编程实践;4、MapReduce编程实践

大数据实验统计 1、Hadoop安装及使用&#xff1b; 一&#xff0e;实验内容 Hadoop安装使用&#xff1a; 1&#xff09;在PC机上以伪分布式模式安装Hadoop&#xff1b; 2&#xff09;访问Web界面查看Hadoop信息。 二&#xff0e;实验目的 1、熟悉Hadoop的安装流程。 2、…

Educational Codeforces Round 133 (Rated for Div. 2) C. Robot in a Hallway

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5; c…

探索async/await的魔力:简化JavaScript异步编程

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

软件设计师28--SQL语言

软件设计师28--SQL语言 考点1&#xff1a;普通查询SQL语言SQL语言 - 查询例题&#xff1a; 考点2&#xff1a;分组查询SQL语言 - 查询例题&#xff1a; 考点3&#xff1a;权限控制SQL语言例题&#xff1a; 考点1&#xff1a;普通查询 SQL语言 SQL语言 - 查询 例题&#xff1a;…