admin管理员组

文章数量:1530848

1 日志清理

其实GLOG很长时间以来都没有日志清理功能。小白对此也很震惊,还特意去查了GLOG的提交记录。代码的提交记录显示,GLOG与日志清理有关的最初代码是2019年11月1日,而这个开源项目的起始时间可以追溯到2008年。也就是说,在长达11年的时间里,这个项目都没有清理日志的功能,甚至开发团队都没有进行相关代码的开发。

所以小白也在网上查询到一些文章,专门提到针对GLOG日志库使用时,由各路好手自己开发的日志清理工具。

如果小白开始使用这个库的时候还在它缺乏如此重要功能的时间段,那大概是会放弃它的吧。不过小白在体验过当前版本(即0.6.0)中的日志清理后,仍然还是有想要吐槽的冲动。

2 GLOG对日志清理功能的描述

在GLOG的ReadMe里,对日志清理功能的描述如下:

Automatically Remove Old Logs
To enable the log cleaner:

google::EnableLogCleaner(3); // keep your logs for 3 days

And then glog will check if there are overdue logs whenever a flush is performed. In this example, any log file from your project whose last modified time is greater than 3 days will be unlink()ed.
This feature can be disabled at any time (if it has been enabled)

google::DisableLogCleaner();

这里看上去非常简单,就是启用一下google::EnableLogCleaner()函数,然后GLOG会在第一次刷新日志的时候把超期的日志清理掉,如果想禁用清理功能,就随时调用一下google::DisableLogCleaner()函数。

唔……轻松愉快?!

事实并非如此。经过小白的测试,有以下几点问题值得吐槽,至少为什么明明有坑却不讲清楚:

  • google::FlushLogFiles()前先写入内容才能清理掉日志;
  • google::FlushLogFiles()只能清理掉对应级别内的日志(而并不是如文档及代码注释所说可以清理掉该级别及以上的日志),比如google::FlushLogFiles(google::GLOG_INFO)就只能清理GLOG_INFO级别的日志。

其中第一点其实很不好:因为清理本身是一个动作,而写入是另一个动作,目前GLOG的做法是把清理这个动作绑定在写入之后进行,差评。

对于第二点,影响倒小一些:通常情况下Warning Error Fatal级别的日志比较少也比较小。但是清理功能的设计需求明明是按时间来筛选,怎么还需要按级别分别设置?

大家可能没意识到,把第一和第二点连起来看,意味着如果要删掉超期的Warning Error Fatal级别的日志,就需要到下一次写入同等级日志并刷新的时候!对于有强迫症的人来说这很难受,不太明白为什么是这样的设计思路,希望开发团队后期能做出点调整。

3 小白的示例

为了说明小白发现的两个问题,还是以上篇文章中控制小数点精度的代码为例:

#define GLOG_NO_ABBREVIATED_SEVERITIES
#include "glog/logging.h"
#include <iostream>
#include <iomanip>
#define WRITE_LOG(s) (LOG(INFO)<<s)

int main(int argc, char* argv[])
{
	FLAGS_log_dir = "../Log/";

	if (!google::IsGoogleLoggingInitialized())
	{
		google::InitGoogleLogging("Alg_Log");
	}
	
	google::EnableLogCleaner(1);

	double pi = 3.141592653;

	// Method1: C语言风格的小数点控制
	char testInfo[128];
	sprintf_s(testInfo, "pi = %.3lf", pi);

	WRITE_LOG(testInfo);        // 尝试注释掉写入动作1
	google::FlushLogFiles(google::GLOG_INFO);


	// Method2: C++语言风格的输出流小数点控制
	LOG(INFO) << std::fixed << std::setprecision(9) << "pi = " << pi;  // 尝试注释掉写入动作2
	google::FlushLogFiles(google::GLOG_INFO);

	if (google::IsGoogleLoggingInitialized())
	{
		google::ShutdownGoogleLogging();
	}

	return 0;
}

如果你和我一样,把写入的两句代码注释掉,你就会发现日志不会被清理掉。

如果你完整执行以上代码,你就会发现:

看到了吧,在没有刷新WARNING ERROR FATAL之前,就是不会清理掉这些等级的日志。

诚以为在这个方面GLOG还需要改进。不过从开发团队给GLOG赋予的版本号来看也确实远不是完全体。希望开发团队能及时发现这些不太合理的地方。

本文标签: 日志glog