Google glog使用說明


一、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_ << "] ";
  }

修改這個地方的格式

 

五、簡單示例(使用默認配置)

1 #include <iostream>
2 #include <glog/logging.h>
3 
4 int main(int argc, char** argv) {
5     google::InitGoogleLogging(argv[0]);
6     LOG(INFO) << "Hello,GOOGLE!";
7 }

 

編譯執行:

g++ test.cpp -lglog -lgflags

./a.out
默認生成路徑為/tmp,cd進入/tmp目錄,可以看到生成了兩個文件:
a.out.INFO 
a.out.test.yanghao.log.INFO.20171208-095841.12698

 

六、增加嚴重度的種類

將系統中用來統計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());

 

 

參考鏈接:

https://github.com/google/glog

 https://www.cnblogs.com/zhoug2020/p/5884598.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM