当前位置: 首页 > 工具软件 > Google Glog > 使用案例 >

Google glog使用说明

能旭
2023-12-01

一、glog是什么:

Google glog是一个基于程序级记录日志信息的c++库,编程使用方式与c++的stream操作类似,例:

LOG(INFO) << "Found " << num << " cookies";

“LOG”宏为日志输出关键字,“INFO”为严重性程度。

主要支持功能:

1, 参数设置,以命令行参数的方式设置标志参数来控制日志记录行为;

2, 严重性分级,根据日志严重性分级记录日志;

3, 可有条件地记录日志信息;

4, 条件中止程序。丰富的条件判定宏,可预设程序终止条件;

5, 异常信号处理。程序异常情况,可自定义异常处理过程;

6, 支持debug功能。可只用于debug模式;

7, 自定义日志信息;

8, 线程安全日志记录方式;

9, 系统级日志记录;

10, google perror风格日志信息;

11, 精简日志字符串信息。

 

二、下载安装

1.下载:https://github.com/google/glog/releases

2.解压安装

tar zxvf glog-0.3.3.tar && cd glog-0.3.3 && ./configure && make && make install

 

三、glog的主要内容

1.日志等级 

  1)系统预定义等级:INFO(=0)<WARNING(=1)<ERROR(=2)<FATAL(=3)以上是简写形式,可通过宏关闭简写形式,其原始定义是有GLOG_前缀.

在windows中可能存在ERROR宏冲突的问题,通过宏监测会在编译器提示.

  2)最严重级别是FATAL级别,对应DEBUG模式是DFATAL级别 

    2.1)在输出FATAL日志消息后,会终止程序运行.

    2.2)DEBUG模式中,DFATAL级别对应ERROR--便于调试,而非 DEBUG模式则对应FATAL.

  3)每个级别都对应有相应的日志文件,日志文件的位置及名称定义如下: 

    3.1)文件默认存放在临时文件中,windows下为 "C:\Users\user_name\AppData\Local\Temp",Linux是"/tmp"

    3.2)文件名称: programname.hostname.user_name.log.severity_level.dat e.time.pid

    3.3)Linux系还会为每个文件创建一个文件链接

  4)日志输出采用如下规则: 

    4.1)每个级别的日志除了输出到对应日志文件中,还输出到每个低级别日志文件中

    4.2)如一个ERROR日志,会输出到INFO,WARNING,ERROR三个日志文件中

    4.3)默认,ERROR和FATAL消息除了输出到日志文件中之外,还会输出到标准错误中

2.DEBUG模式支持

  1)DEBUG模式日志输出形式,增加前缀D表示DEBUG模式日志,如DLOG(log_severity),DLOG_IF(log_severity,condition)

  2)采用DEBUG宏控制,非DEBUG模式中DEBUG日志不会编译进程序就避免了程序冗余

3.丰富的助手宏

功能类似assert断言,但不受DEBUG模式控制即非DEBUG模式也生效.如果验证失败,会写FATAL日志并终止程序运行.

  1)比较验证

  CHECK_EQ(arg1,arg2)

  CHECK_NE(arg1,arg2)

  CHECK_LE(arg1,arg2)

  CHECK_LT(arg1,arg2)

  CHECK_GE(arg1,arg2)

  CHECK_GT(arg1,arg2)

  2)CHECK_NOTNULL(arg)

  3)字符串比较

  CHECK_STREQ

  CHECK_STRNE

  CHECK_STRCASEEQ

  CHECK_STRCASENE

4.特定的信息处理

  1)针对可能导致程序崩溃的信号会输出dump信息

  2)处理的信号包括:SIGSEGV,SIGILL,SIGABRT,SIGBUS,SIGTERM

  3)相关函数:

  google::InstallFailureSignalHandler() ,信号处理函数。

  google::InstallFailureWriter(void (writer)(const char data,int size)) 默认dump信息输出到STDERR,可通过该函数定制dump输出目标。

5.日志类型

LOG    //内置日志

VLOG    //自定义日志

DLOG    //DEBUG模式可输出的日志

DVLOG    //DEBUG模式可输出的自定义日志

SYSLOG    //系统日志,同时通过 syslog() 函数写入到/var/log/message 文件

PLOG    //perror风格日志,设置errno状态并输出到日志中

RAW_LOG       //线程安全的日志,需要#include <glog/raw_logging.h>

6.几个常用参数

  FLAGS_logtostderr = true; // 设置日志消息是否转到标准输出而不是日志文件

  FLAGS_alsologtostderr = true; // 设置日志消息除了日志文件之外是否去标准输出

  FLAGS_colorlogtostderr = true; // 设置记录到标准输出的颜色消息(如果终端支持)

  FLAGS_log_prefix = true; // 设置日志前缀是否应该添加到每行输出

  FLAGS_logbufsecs = ; // 设置可以缓冲日志的最大秒数,0指实时输出

  FLAGS_max_log_size = ; // 设置最大日志文件大小(以MB为单位)

  FLAGS_stop_logging_if_full_disk = true; // 设置是否在磁盘已满时避免日志记录到磁盘

7.几个常用函数

  google::SetLogDestination(google::INFO, "log/INFO_"); // 设置特定严重级别的日志的输出目录和前缀。第一个参数为日志级别,第二个参数表示输出目录及日志文件名前缀

  google::SetLogFilenameExtension("logExtension"); // 在日志文件名中级别后添加一个扩展名。适用于所有严重级  

  google::SetStderrLogging(google::INFO); // 大于指定级别的日志都输出到标准输出

  google::InstallFailureSignalHandler(); // 将 coredumped 信息输出到 stderr

 

四、自定义日志打印格式

要自定义glog输出格式并不难,可以直接修改logging.cc文件中的LogMessage::Init函数,修改的位置:

glog大部分常用功能在该文件中实现,可通过修改该文件来实现自己想要的功能

if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
    stream() << LogSeverityNames[severity][0]
             << setw(2) << 1+data_->tm_time_.tm_mon
             << setw(2) << data_->tm_time_.tm_mday
             << ' '
             << setw(2) << data_->tm_time_.tm_hour  << ':'
             << setw(2) << data_->tm_time_.tm_min   << ':'
             << setw(2) << data_->tm_time_.tm_sec   << "."
             << setw(6) << usecs
             << ' '
             << setfill(' ') << setw(5)
             << static_cast<unsigned int>(GetTID()) << setfill('0')
             << ' '
             << data_->basename_ << ':' << data_->line_ << "] ";
  }

五、增加严重度的种类

将系统中用来统计profile的日志单独打印到一个日志文件中,以便于定位问题与分析性能问题,所以我增加了一个LOG(PROFILE)的日志格式

修改以下源码部分(修改后记得重新编译):

src/logging.cc:337:  "INFO", "WARNING", "ERROR", "FATAL", "PROFILE"
src/glog/logging.h:418:#define COMPACT_GOOGLE_LOG_PROFILE google::LogMessage( \
src/glog/logging.h:419:      __FILE__, __LINE__, google::GLOG_PROFILE)
src/glog/logging.h:420:#define LOG_TO_STRING_PROFILE(message) google::LogMessage( \
src/glog/logging.h:421:      __FILE__, __LINE__, google::GLOG_PROFILE, message)
src/glog/logging.h:423:#define COMPACT_GOOGLE_LOG_PROFILE google::NullStream()
src/glog/logging.h:424:#define LOG_TO_STRING_PROFILE(message) google::NullStream()
src/glog/logging.h:466:#define GOOGLE_LOG_PROFILE(counter)  \
src/glog/logging.h:467:  google::LogMessage(__FILE__, __LINE__, google::GLOG_PROFILE, counter, \
src/glog/logging.h:469:#define SYSLOG_PROFILE(counter)  \
src/glog/logging.h:470:  google::LogMessage(__FILE__, __LINE__, google::GLOG_PROFILE, counter, \
src/glog/logging.h.in:418:#define COMPACT_GOOGLE_LOG_PROFILE @ac_google_namespace@::LogMessage( \
src/glog/logging.h.in:419:      __FILE__, __LINE__, @ac_google_namespace@::GLOG_PROFILE)
src/glog/logging.h.in:420:#define LOG_TO_STRING_PROFILE(message) @ac_google_namespace@::LogMessage( \
src/glog/logging.h.in:421:      __FILE__, __LINE__, @ac_google_namespace@::GLOG_PROFILE, message)
src/glog/logging.h.in:423:#define COMPACT_GOOGLE_LOG_PROFILE @ac_google_namespace@::NullStream()
src/glog/logging.h.in:424:#define LOG_TO_STRING_PROFILE(message) @ac_google_namespace@::NullStream()
src/glog/logging.h.in:466:#define GOOGLE_LOG_PROFILE(counter)  \
src/glog/logging.h.in:467:  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_PROFILE, counter, \
src/glog/logging.h.in:469:#define SYSLOG_PROFILE(counter)  \
src/glog/logging.h.in:470:  @ac_google_namespace@::LogMessage(__FILE__, __LINE__, @ac_google_namespace@::GLOG_PROFILE, counter, \
src/glog/log_severity.h:47:const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3, GLOG_PROFILE = 4,
src/glog/log_severity.h:54:  ERROR = GLOG_ERROR, FATAL = GLOG_FATAL, PROFILE = GLOG_PROFILE;

测试:

#include <iostream>
#include <glog/logging.h>
#include <cstdlib>

int main(int argc, char** argv) {
    google::InitGoogleLogging(argv[0]);
    // create logpath
    std::string str_des;
    str_des.append("mkdir -p ");
    str_des.append("log");
    system(str_des.c_str());
    // INFO
    std::string str_info;
    str_info.append("./log");
    str_info.append("/INFO_");
    google::SetLogDestination(google::INFO, str_info.c_str());
    // WARNING
    std::string str_warn;
    str_warn.append("./log");
    str_warn.append("/WARNING_");
    google::SetLogDestination(google::WARNING, str_warn.c_str());
    LOG(WARNING) << "The is a warning!";
    // my own type
    std::string str_pro;
    str_pro.append("./log");
    str_pro.append("/PROFILE_");
    google::SetLogDestination(google::WARNING, str_pro.c_str());
    LOG(WARNING) << "The is my own type!";
    // stop glog
    google::ShutdownGoogleLogging();
编译执行:
g++ -g test.cpp -lglog -lgflags &&  ./a.out
 
之后在该目录下会生成一个log目录
a.out  log  test.cpp
 
cd log
a.out.INFO  a.out.WARNING  a.out.PROFILE  INFO_20171208-151843.18256  PROFILE_20171208-151843.18256  WARNING_20171208-151843.18256
 
打开PROFILE_20171208-151843.18256
  1 Log file created at: 2017/12/08 15:18:43
  2 Running on machine: test
  3 Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
  4 W1208 15:18:43.879918 18256 test.cpp:28] The is my own type!
 
如果系统长时间运行,可以设置日志文件的大小,当文件超过该限制后就会重新生成一个新的log文件,glog有提供该功能
glog在Mac上可能存在打印线程号错误的情况, 此时修改glog源代码中的utilities.cc文件中的GetTID()接口,将最后一行
return (pid_t)(uintptr_t)pthread_self();改为
return ::pthread_mach_thread_np(pthread_self());

 

 类似资料: