使用GLOG控制C++程序输出
一、简介与安装
Google Glog是Google的一个开源库,用于实现应用级别的logging。 它提供了一系列类似于C++流风格的(注意在后面代码中留意)logging API,以及一些预定义的宏。它有点类似于C里面的assert,但是比它具备更丰富的输出信息以及使用灵活性。
具体来说,GLOG支持以下功能:
◆ 参数设置,以命令行参数的方式设置标志参数来控制日志记录行为;
◆ 严重性分级,根据日志严重性分级记录日志;
◆ 可有条件地记录日志信息;
◆ 条件中止程序。丰富的条件判定宏,可预设程序终止条件;
◆ 异常信号处理。程序异常情况,可自定义异常处理过程;
◆ 支持debug功能;
◆ 自定义日志信息;
◆ 线程安全日志记录方式;
◆ 系统级日志记录;
◆ google perror风格日志信息;
◆ 精简日志字符串信息
接下来记录GLOG在ubuntu和Mac上的安装:
- Ubuntu:通过编译安装
./configure --preifx=mypath
make
make install
- Mac:直接通过homebrew安装
brew install glog
二、简单使用
下面可以通过一段简单的代码了解GLOG的使用
// Usage: g++ glogtest.cpp -o glogtest -lglog
// reference: * https://blog.csdn.net/Solomon1558/article/details/52558503
// * https://zhuanlan.zhihu.com/p/26025722
#include <iostream>
#include <string>
#include <glog/logging.h>
int main(int argc, char** argv) {
FLAGS_alsologtostderr = 1;
google::InitGoogleLogging(argv[0]);
//通过SetLogDestination可能没有设置log_dir标志位的方式方便(会遗漏一些日志)
//google::SetLogDestination(google::GLOG_INFO, "/tmp/today");
//标志位
FLAGS_colorlogtostderr=true; //设置输出颜色
FLAGS_v = std::atoi(argv[1]); //设置最大显示等级(超过该等级将不记录log)
FLAGS_log_dir = "./logs";
LOG(INFO) << "Found " << google::COUNTER << " arguments!";
// assert
CHECK(access(argv[2], 0) != -1) << "No such file: "<<argv[2];
LOG(INFO) << "I am INFO!";
LOG(WARNING) << "I am WARNING!";
LOG(ERROR) << "I am ERROR!";
//VLOG用来自定义日志, 可以在括号内指定log级别
VLOG(1) << "[Custom log(VLOG)] Level 1!";
VLOG(2) << "[Custom log(VLOG)] Level 2!";
VLOG(3) << "[Custom log(VLOG)] Level 3!";
VLOG(4) << "[Custom log(VLOG)] Level 4! This is used for detailed message which need not to be printed each time.";
VLOG(5) << "[Custom log(VLOG)] Level 5! On this level messages are print as detail as possible for debugging.";
LOG(FATAL) << "I am FATAL!";
return 0;
}
①代码分析
可以看出,glog的使用有以下需要注意:
-
Setup:
首先include<glog/logging.h>头文件。然后需要在使用前初始化glog并设置要用到的标志位。上面代码设置了三个标志位,分别是开启输出颜色显示;最大log等级以及log重定向的位置。 -
常用的宏
上面代码中出现了几个glog中常用的关键字:
- LOG:内置日志,可以看做一个ostream,向屏幕输出的同时可以重定向到其他位置,类似于bash中的 $cmd 2>&1 | tee xx.log(不严格)
- INFO / WARNING / ERROR / FATAL:代表了不同的log级别。其中FATAL的出现会直接导致程序中断。ERROR不会中断程序,但是对应的LOG会显示为红色;WARNING对应LOG会显示为黄色。
- VLOG:自定义日志,括号中的数字越大则对应log级别越高。只有log级别小于FLAGS_v标志位的,在代码运行阶段才会被打印出来。
- COUNTER:注意上面代码中COUNTER用的不对...该关键字并不是用来记录输入参数个数的...而是用来统计某个代码被执行了多少次。
-
CHECK宏:类似于Assert,见下图
Fig. 1 Check宏简介
上面的例子是在代码中检查某个路径是否存在。该功能是由access实现的,如果文件具有指定的访问权限,则函数返回0;如果文件不存在或者不能访问指定的权限,则返回-1.
②编译
这里还是使用g++对cpp文件进行编译。不过在编译包含glog的代码时需要额外加一个参数:-lglog。为了方便起见我们可以把编译命令作为一个函数放在bashrc中:
function compile_gcc(){
file=$1
g++ -std=c++11 $file -o ${file: 0:-4} -lglog
}
③执行
Fig. 2 执行./glogtest 4 ~/Downloads的结果
当access返回0时,程序可以继续。可以看到由于第一个参数log_v设置为4,VLOG对应1-4级的log信息均打印出来了。下图显示了此时logs文件夹下重定向的日志。
值得注意的是,此时logs文件夹下有两种颜色的文件,其中白色为普通日志文件,包含了精确的时间戳信息,会随着程序的运行不断累积;紫色的日志文件则为最近一次的log信息。
日志文件的命名:
由于/data路径不存在,程序在CHECK之后出现中断。此时的logs文件夹内容如下:
Fig. 5 执行第二次之后logs文件夹下的日志
-
四种log的内容大概如下 (文本内容为第一次执行后的log)
Fig. 6 四种级别log内容
三、进阶使用
涉及GLOG的更多知识,以后用到了再详细记录。这里先大概介绍下相关的功能。
3.1 条件日志
LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies"; //当条件满足时输出日志
LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie"; //第一次执行以后每隔十次记录一次log
LOG_IF_EVERY_N(INFO, (size > 1024), 10) //上面两者的结合
LOG_FIRST_N(INFO, 20) // 此语句执行的前20次都输出日志;后面执行不输出日志
3.2 DEBUG
3.3 Wrapper
#define CY_LTRACE(tag) VLOG(5) << "[TRACE] [" << (#tag) << "] "
#define CY_LDEBUG(tag) VLOG(4) << "[DEBUG] [" << (#tag) << "] "
#define CY_LINFO(tag) VLOG(3) << "[INFO] [" << (#tag) << "] "
#define CY_LERROR(tag) LOG(ERROR) << "[ERROR] [" << (#tag) << "] "
#define CY_LWARN(tag) LOG(WARNING) << "[WARN] [" << (#tag) << "] "
#define CY_LFATAL(tag) LOG(FATAL) << "[FATAl] [" << (#tag) << "] "
四、参考
https://zhuanlan.zhihu.com/p/26025722
https://blog.csdn.net/Solomon1558/article/details/52558503
https://blog.csdn.net/qq_34347375/article/details/86629421