本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。
文章目录
glog版本为:https://github.com/google/glog/archive/refs/tags/v0.6.0.zip
Motivation
我们项目本身的日志都是使用trpc的日志模块打印的,依赖项目中的日志是使用glog打印的,希望将日志等级调整为INFO,调试依赖项目中的代码。
但是实际的测试过程中发现在代码中添加下述代码,且确保未开启NDEBUG的情况下:
FLAGS_stderrthreshold = 0;
FLAGS_minloglevel = 0;
FLAGS_v = 4;
所有的LOG(INFO)与VLOG无法打印,但是LOG(WARNING)和LOG(ERROR)可以正常打印。
因为本身是一个推进必要进度之外的事情,所以希望用最快的方式解决,google后没有发现类似的问题,差一点点就想把所有外部框架的日志直接宏替换了。。。但是确实太丑陋的了,虽然我不是一个对代码有特别高追求的人,但是实在是太挫了,还是花了两个小时去解决这个问题。
具体的思路是大概了解下glog框架的原理,然后直接gdb去对比LOG(INFO),VLOG和LOG(WARNING),LOG(ERROR)执行路径的区别,确定没有打印的实际原因是什么。
glog的大概原理是在记录LOG时生成一个LogMessage对象,在析构函数中Flush,具体可以参考[1]。
Process
第一个断点打在304行,单步调试进去
发现LOG(INFO)没有进入google::LogMessage::Init,直接跳到了NullStream的构造流程
而LOG在宏展开后其实是COMPACT_GOOGLE_LOG_INFO
而后的LOG(WARNING),LOG(ERROR)可以正常的进入google::LogMessage::Init
这个时候去找NullStream的构造流程,发现GOOGLE_STRIP_LOG宏其实控制了NullStream的构造流程
去我们的项目里面搜了一个,不知道哪个哥在一个极其隐蔽的地方塞了一个GOOGLE_STRIP_LOG=1,这就会导致LOG(INFO)默认构造NullStream,从而导致不执行实际的LogMessage init和flush流程,也就不打印日志了。
至于为什么VLOG也无法打印,可以从源码中看到VLOG其实展开后也是LOG(INFO),这就全部说的通了
只需要在logging.h前声明GOOGLE_STRIP_LOG为0就可以了,然后所有的问题就解决了。
#define GOOGLE_STRIP_LOG 0
#include <glog/logging.h>
参考: