使用GLOG控制C++程序输出

2019-10-09  本文已影响0人  吃远

一、简介与安装

  Google Glog是Google的一个开源库,用于实现应用级别的logging。 它提供了一系列类似于C++流风格的(注意在后面代码中留意)logging API,以及一些预定义的宏。它有点类似于C里面的assert,但是比它具备更丰富的输出信息以及使用灵活性。

  具体来说,GLOG支持以下功能:

   ◆ 参数设置,以命令行参数的方式设置标志参数来控制日志记录行为;
   ◆ 严重性分级,根据日志严重性分级记录日志;
   ◆ 可有条件地记录日志信息;
   ◆ 条件中止程序。丰富的条件判定宏,可预设程序终止条件;
   ◆ 异常信号处理。程序异常情况,可自定义异常处理过程;
   ◆ 支持debug功能;
   ◆ 自定义日志信息;
   ◆ 线程安全日志记录方式;
   ◆ 系统级日志记录;
   ◆ google perror风格日志信息;
   ◆ 精简日志字符串信息

  接下来记录GLOG在ubuntu和Mac上的安装

./configure --preifx=mypath
make
make install
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的使用有以下需要注意:

  1. Setup:
    首先include<glog/logging.h>头文件。然后需要在使用前初始化glog并设置要用到的标志位。上面代码设置了三个标志位,分别是开启输出颜色显示;最大log等级以及log重定向的位置。

  2. 常用的宏
    上面代码中出现了几个glog中常用的关键字:

上面的例子是在代码中检查某个路径是否存在。该功能是由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信息。

  日志文件的命名:
<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>

Fig. 3 执行一次以后logs文件夹下的日志 Fig. 4 执行./glogtest 4 /data的结果

由于/data路径不存在,程序在CHECK之后出现中断。此时的logs文件夹内容如下:


Fig. 5 执行第二次之后logs文件夹下的日志

三、进阶使用

  涉及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

上一篇下一篇

猜你喜欢

热点阅读