开源项目--Glog
Glog的使用,以及一些本人定制过程
开源项目--Glog
简述 Glog
Glog 是 google 的开源日志系统,我自己接触的第一个日志库就是 Glog,习惯了,对于我一直以来的工作,我的应用程度上也没有什么缺点,反而有些我觉得很方便的地方,Glog 的特性官方的描述我就不粘贴了,百度一大把,下面会结合一点实际场景说明我觉好用的地方
- 最简单的启用
google::InitGoogleLogging("LogName"); - 输出语句也很简单,自动补回车,自行加回车也不会输出一个空行,下面两句输出结果一致
1
2
LOG(INFO) << "abc";
LOG(INFO) << "abc\n";
- 输出内容不需要调整的情况下,基本满足 DEBUG 需求,如带有文件名和行数:
等级+日期 时间 PID 文件:行数
I0514 15:52:26.102143 96944 [common.cpp:59] 1a 1d 65 94 1a e2 f3 31 - 输出文件也方便,默认按照 PID 新建文件,携带新建时间,尤其方便的是会建立软链接到最新创建的日志,查看日志只需要查看软链接,免去了判断哪个文件才是当前最新的烦恼
- 代码量不多(我没有对比过其他日志库的源码),对应不同场景,可以尝试修改源码适配不同工程,如本人修改了文件的命名格式,以及新建日志文件的条件增加按天新建功能(则 pid 或者日期改变都将新建一个日志文件)
Glog 使用示例
1
2
3
4
5
6
7
8
9
10
11
#include <glog/logging.h>
int main(){
google::InitGoogleLogging("LogName");
google::SetLogDestination(google::INFO, "/var/logs/LogName-");
google::SetLogDestination(google::WARNING, "var/logs/LogName-");
google::SetLogDestination(google::ERROR, "/var/logs/LogName-");
FLAGS_logbufsecs = 0; //缓冲日志输出,默认为30秒,此处改为立即输出
FLAGS_stop_logging_if_full_disk = true; //当磁盘被写满时,停止日志输出
FLAGS_minloglevel = 0;//INFO=0,WARNING=1,ERROR=2
LOG(INFO) << "Build time : " << __DATE__ << " - " << __TIME__;//输出编译时间
}
大多数设置有默认值,而更多设置可以直接查看头文件:
- 搜索带”set”关键字的方法,如:SetLogDestination
- 搜索”DECLARE_“,可以找到一系列 GFLAG 变量,如最小输出等级的定义:
DECLARE_int32(minloglevel);
那么我们可以用以下语句来修改(也可以运行程序时带参数指定):
FLAGS_minloglevel = 0; - 另外查看头文件也能发现很多其他应用,如有一系列结合断言的 LOG 宏(如 LOG_ASSERT)等等,本人并未使用,比多做描述
根据需求定制自己的 Glog
例如,本人工作上希望日志能按天区分每一个文件,这样避免一个文件太大,以及查错方便等等
首先我们可以简单浏览以下源码,新建日志文件主要是每次 Write 时判断以下条件
src\logging.cc : LogFileObject::Write
1
2
if (static_cast<int>(file_length_ >> 20) >= MaxLogSize() ||
PidHasChanged() )
src\utilities.cc : PidHasChanged
1
2
3
4
5
6
7
8
9
static int32 g_main_thread_pid = getpid();
bool PidHasChanged() {
int32 pid = getpid();
if (g_main_thread_pid == pid) {
return false;
}
g_main_thread_pid = pid;
return true;
}
可见,我们只需要仿照着写一个函数,加入到条件判断,即可符合我们的需求
src\logging.cc : LogFileObject::Write
1
2
if (static_cast<int>(file_length_ >> 20) >= MaxLogSize() ||
PidHasChanged() || DayHasChanged())
src\utilities.cc : DayHasChanged
1
2
3
4
5
6
7
8
9
10
11
12
13
static int32 g_main_day = 0;
bool DayHasChanged()
{
time_t raw_time;
struct tm tm_info={0};
time(&raw_time);
localtime_r(&raw_time,&tm_info);
if (tm_info.tm_mday == g_main_day){
return false;
}
g_main_day = tm_info.tm_mday;
return true;
}
再有,我当时觉得文件名时间去到了时分秒没必要,反而因为文件名太长在显示上觉得不舒服
同样,不难发现还是在 src\logging.cc : LogFileObject::Write 方法中,新建文件时构造了文件名的格式,主要涉及以下变量
ostringstream time_pid_stream; 找到了这个变量,接下来的几行代码,就可以随意修改成更适合当前工程上使用的版本了
1
2
3
4
5
6
7
8
9
10
11
12
ostringstream time_pid_stream;
time_pid_stream.fill('0');
time_pid_stream << 1900+tm_time.tm_year
<< setw(2) << 1+tm_time.tm_mon
<< setw(2) << tm_time.tm_mday
// << '-'
// << setw(2) << tm_time.tm_hour
// << setw(2) << tm_time.tm_min
// << setw(2) << tm_time.tm_sec
<< '-'
<< GetMainThreadPid()
<< ".log";
This post is licensed under CC BY 4.0 by the author.