glog使用


How To Use Google Logging Library

Glog 的基本使用方法在google code上有介紹:How To Use Google Logging Library ;最好有VPN,不然訪問的時候估計又是加載不了,吐槽下GFW

以下對 上述文檔的翻譯大部分來自 :Glog 使用幫助 ,這位哥們寫的也是轉的,但是沒出處,所以原文在出自哪里我也不清楚,感謝不知名人士。少部分來自我自己的補充,有不對之處希望指出;

1.   概述

      Google glog是一個基於程序級記錄日志信息的c++庫,編程使用方式與c++stream操作類似,例:

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

LOG”宏為日志輸出關鍵字,“INFO”為嚴重性程度。

主要支持功能:

1, 參數設置,以命令行參數的方式設置標志參數來控制日志記錄行為;

2, 嚴重性分級,根據日志嚴重性分級記錄日志;

3, 可有條件地記錄日志信息;

4, 條件中止程序。豐富的條件判定宏,可預設程序終止條件;

5, 異常信號處理。程序異常情況,可自定義異常處理過程;

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

7, 自定義日志信息;

8, 線程安全日志記錄方式;

9, 系統級日志記錄;

10, google perror風格日志信息;

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

2.   功能使用

1.1  參數設置

       可通過命令行方式設置glog的標志參數,用來控制日志記錄行為。

命令格式如下:

      標志名1 = 標志值 標志名2=標志值 …… 標志值n=標志值        ./程序名

所有標志名需添加統一前綴—“GLOG_”,不同標志語句之間以空格相隔;

例如:

-- GLOG_vmodule=mapreduce=2,file=1,gfs*=3  -- GLOG_v=0 ./application.exe

常用標志參數類型及其作用說明:

標志參數

類型

作用

logtostderr

bool

值為true的時候,日志信息輸出到stderr,並非文件。默認值為 false

stderrthreshold

int

嚴重性級別在該門限值以上的日志信息除了寫入日志文件以外,還要輸出到stderr。各嚴重性級別對應的數值:INFO0WARNING1ERROR2FATAL3

默認值為2.

minloglevel

int

嚴重性級別在該門限值以上的日志信息才進行記錄。

默認值為0.

log_dir

string

日志信息記錄路徑。默認為空,如果沒有指定信息輸出到stderr,則信息保存在"/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>"文件中。 (e.g., "/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474").

v

int

對於使用“ VLOG(m)”(mint型)表達式進行輸出的日志信息,只在m的值小於該標志的值的時候,才進行輸出。另外, 該設置可能被 vmodule標志給覆蓋.默認為0.

vmodule

string

分模塊(文件)設置VLOG(m)日志信息的輸出基本。命令格式為以逗號分開的“<module name>=<log level>”表達式組成。其中<module name> 是“glob pattern”,支持通配符,<module name>不包括文件的擴展名(.h,.cc等)。

1標志說明

還有其他的標志參數定義在logging.cc,可在文件中搜索“DEFINE_”來進行查看。

1.2     嚴重性分級記錄信息

glog可通過根據指定的嚴重性等級,來選擇性記錄日志。日志信息嚴重性等級按由低到高排列依次為:INFO,WARNING, ERROR, 和 FATAL四級。使用者可以在命令行中設置嚴重性等級門限值來控制日志的輸出,詳細見“參數設置”部分的“minloglevel”標志值的介紹。

1.3     有條件地記錄日志信息

glog可以控制日志信息在指定條件下進行記錄。具體使用如下:

1, LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";

上面的語句表示,只有當num_cookies > 10條件成立時,“Got lots of cookies”日志信息才被記錄。

2, LOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie";

上面的語句表示,在程序中周期性的記錄日志信息,在該語句第11121……次被執行的時候,記錄日志信息。COUNTER變量表示該語句被執行的次數。

3, LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER<< 
"th big cookie";

上面的語句為12項功能的合並,size>1024的條件連續成立10次的時候記錄日志信息。COUNTER變量表示該條件成立的次數。

4, LOG_FIRST_N(INFO, 20) << "Got the " << COUNTER << "th cookie";

上面的語句表示,當該語句只在首次執行了20次以后記錄日志信息, COUNTER變量表示該語句被執行的次數。

1.4     有條件地中止程序

       glog提供了CHECK宏,用於在調試地時候中止程序,及早發現程序錯誤。當通過該宏指定的條件不成立的時候,程序會中止,並且記錄對應的日志信息。功能類似於ASSERT,區別是CHECK宏不受NDEBUG約束,在release版中同樣有效。具體使用如下:

                 CHECK(fp->Write(x) == 4) << "Write failed!";

       當fp->Write(x) == 4成立時,記錄“Write failed!”日志信息,並且中止程序,其中fp->Write(x) == 4為判定條件,日志信息以c++stream操作形式生成。

glog提供了多個便利的宏來處理特定關系的判定。具體有:

1,判定大小關系

CHECK_EQ, CHECK_NE, CHECK_LE, CHECK_LT, CHECK_GE, CHECK_GT,使用這些宏需要注意類型一致,如果出現類型不一致的,可使用static_cast轉換。

2,判定指針是否為空

        CHECK_NOTNULLsome_ptr),可用於對象初始化的時候。

3,判定字符串是否相等

         CHECK_STREQ, CHECK_STRNE, CHECK_STRCASEEQ, CHECK_STRCASENE。可進行大小寫敏感或不敏感字符串來分別判定。

4,     判定浮點是否相等或相近

CHECK_DOUBLE_EQCHECK_NEAR。這兩個宏都需要指定一個可容忍的偏差上限。

當這些宏判定條件不成立時,glog會生成一個FATAL級別的日志信息,該信息包含比較的兩個值和stream方式傳入的字符串,然后中止程序。

1.5     異常信號處理

      glog提供了比較方便的程序異常處理機制。例如,當程序出現SIGSEGV異常信號時,glog的默認異常處理過程會導出非常有用的異常信息。異常處理過程可以通過google::InstallFailureSignalHandler()來自定義。下面為異常處理過程的輸出例子:

*** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date ***

*** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: ***

PC: @           0x412eb1 TestWaitingLogSink::send()

    @     0x7f892fb417d0 (unknown)

    @     0x412eb1 TestWaitingLogSink::send()

    @     0x7f89304f7f06 google::LogMessage::SendToLog()

    @     0x7f89304f35af google::LogMessage::Flush()

    @     0x7f89304f3739 google::LogMessage::~LogMessage()

    @     0x408cf4 TestLogSinkWaitTillSent()

    @     0x4115de main

    @     0x7f892f7ef1c4 (unknown)

    @     0x4046f9 (unknown)

默認情況下,異常信息是輸出到stderr,通過InstallFailureWriter()可以改變輸出目標。

1.6     支持debug功能

      glog提供特定的宏只在debug模式下生效。以下分別對應LOGLOG_IFDLOG_EVERY_N操作的專用宏。

   DLOG(INFO) << "Found cookies";

   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";

   DLOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie";

1.7     自定義日志信息

        glog提供VLOG宏,讓用戶自定義分級信息,該分級與LOG宏對應的嚴重性分級是獨立管理,在命令行參數設置中獨立設置“v”或“vmodule”參數來控制,具體見“參數設置”部分標志說明。VLOG宏便於用戶調試、查找完問題以后,屏蔽日志信息,減輕負擔。具體使用如下:

  VLOG_IF(1, (size > 1024))<< "I'm printed when size is more than 1024 and when you run the ""program with --v=1 or more";

       上面的語句,只有在size>1024成立時且命令行參數v的值不小於1,才記錄日志信息。

  VLOG_EVERY_N(1, 10)<< "I'm printed every 10th occurrence, and when you run the program ""with --v=1 or more. Present occurence is " << COUNTER;

       上面的語句,只有在命令行參數v的值不小於1時,才會每執行10次記錄一次日志信息。

  VLOG_IF_EVERY_N(1, (size > 1024), 10)<< "I'm printed on every 10th occurence of case when size is more "" than 1024, when you run the program with --v=1 or more. "; "Present occurence is " << COUNTER;

       上面的語句,只有在命令行參數v的值不小於1時,若size>1024條件連續成立10次,記錄一次日志信息。

1.8     線程安全日志記錄

      glog提供了線程安全的日志記錄方式。在<glog/raw_logging.h>文件中提供了相關的宏,如,RAW_CHECKRAW_LOG等。這些宏的功能與CHECKLOG等一致,除此以外支持線程安全,不需要為其分配任何內存和提供額外的鎖(lock)機制。

1.9     系統級日志記錄

  glog除了提供了普通的日志記錄宏,還提供SYSLOG, SYSLOG_IF,和 SYSLOG_EVERY_N宏,這些宏將日志信息通過syslog()函數記錄到系統日志。這個貌似只支持linuxwindows 編譯的時候無法通過,報的錯的是找不到 syslog()函數,而且使用到的syslog.h也找不到;

1.10   google perror風格日志信息

     glog提供了與LOG*CHECK宏作用等價的PLOG()PLOG_IF() PCHECK()宏,不同的是,后者在記錄日志信息的時候,會將errno的狀態及其描述附加到日志描述中。

如:

PCHECK(write(1, NULL, 2) >= 0) << "Write NULL failed";

當條件不成立時,會輸出日志信息:

F0825 185142 test.cc:22] Check failed: write(1, NULL, 2) >= 0 Write NULL failed: Bad address [14]

1.11   精簡日志字符串信息

      日志信息的字符串會占用比較大的內存空間,另外還帶來隱私泄露的問題。glog提供了GOOGLE_STRIP_LOG宏在編譯時候去除日志的字符串信息。

3.   其他說明

1, windows平台使用注意

因為glog的嚴重性級別中使用了ERROR宏,與<windows.h>文件中沖突,可通過以下兩種方式避免:

     a,在包含<windows.h>文件之前,定義宏WIN32_LEAN_AND_MEAN 或者NOGDI

     b,在包含<windows.h>文件之后,undefERROR定義。

2FLAGS_V 編譯的時候報錯error LNK2001: unresolved external symbol

需要包含這兩個頭文件

#include "config_for_unittests.h"

#include "utilities.h"

 

 4.基本代碼

using namespace GOOGLE_NAMESPACE; //必須包含

 

int main(int argc,char *argv[])

{

google::InitGoogleLogging(argv[0]); //初始化log,參數argv[0]就是程序名

 

// 像下面對INFO、ERROR、WARNING 三個級別的錯誤日志都指明了存放位置,如果是同一個位置的話三個文件會合在一起成為一個文件;假設我們只指定INFO文件位置的話,在指定位置的日志里我們可以看到文件中包含的日志也有ERROR、WARNING,但是在windows TEMP 目錄下也會生成兩個文件,一個是WARING,一個是ERROR;
google::SetLogDestination(google::INFO,installPath.c_str()); //INFO級別的日志都存放到installPath目錄下
google::SetLogDestination(google::ERROR,installPath.c_str());//ERROR級別的日志都存放到installPath目錄下
google::SetLogDestination(google::WARNING,installPath.c_str());//WARNING級別的日志都存放到installPath目錄下

google::SetStderrLogging(google::INFO); //輸出到標准輸出的時候大於INFO級別的都輸出;

 

FLAGS_logbufsecs = 0; //日志實時輸出
FLAGS_max_log_size = 1024; // max log size is 1024M

return 0;

}

 初始化日志模塊的時候設置一些以下的參數在頭文件src/glog/logging.h中

// Set whether log messages go to stderr instead of logfiles
DECLARE_bool(logtostderr);

// Set whether log messages go to stderr in addition to logfiles.
DECLARE_bool(alsologtostderr);

// Set color messages logged to stderr (if supported by terminal).
DECLARE_bool(colorlogtostderr);

// Log messages at a level >= this flag are automatically sent to
// stderr in addition to log files.
DECLARE_int32(stderrthreshold);

// Set whether the log prefix should be prepended to each line of output.
DECLARE_bool(log_prefix);

// Log messages at a level <= this flag are buffered.
// Log messages at a higher level are flushed immediately.
DECLARE_int32(logbuflevel);

// Sets the maximum number of seconds which logs may be buffered for.
DECLARE_int32(logbufsecs);

// Log suppression level: messages logged at a lower level than this
// are suppressed.
DECLARE_int32(minloglevel);

// If specified, logfiles are written into this directory instead of the
// default logging directory.
DECLARE_string(log_dir);

// Sets the path of the directory into which to put additional links
// to the log files.
DECLARE_string(log_link);

DECLARE_int32(v); // in vlog_is_on.cc

// Sets the maximum log file size (in MB).
DECLARE_int32(max_log_size);

// Sets whether to avoid logging to the disk if the disk is full.
DECLARE_bool(stop_logging_if_full_disk);

 

 

int64 base_num_infos = LogMessage::num_messages(GLOG_INFO); //INFO 級別日志數量
int64 base_num_warning = LogMessage::num_messages(GLOG_WARNING); //WARNING級別日志數量
int64 base_num_errors = LogMessage::num_messages(GLOG_ERROR); //ERROR級別日志數量


 

for ( int i = 0; i < 10; ++i ) {
int old_errno = errno;
errno = i;
PLOG_EVERY_N(ERROR, 2) << "Plog every 2, iteration " << COUNTER;
errno = old_errno;

LOG_EVERY_N(ERROR, 3) << "Log every 3, iteration " << COUNTER << endl;
LOG_EVERY_N(ERROR, 4) << "Log every 4, iteration " << COUNTER << endl;

LOG_IF_EVERY_N(WARNING, true, 5) << "Log if every 5, iteration " << COUNTER;
LOG_IF_EVERY_N(WARNING, false, 3)
<< "Log if every 3, iteration " << COUNTER;
LOG_IF_EVERY_N(INFO, true, 1) << "Log if every 1, iteration " << COUNTER;
LOG_IF_EVERY_N(ERROR, (i < 3), 2)
<< "Log if less than 3 every 2, iteration " << COUNTER;
}

LOG_IF(WARNING, true) << "log_if this";
LOG_IF(WARNING, false) << "don't log_if this";

DLOG(INFO)<<"ONLY PRINT FOR DEBUG COMPILE";
DLOG_IF(INFO,true)<<"ONLY PRINT FOR DEBUG COMPILE";
DLOG_EVERY_N(INFO,1)<<"ONLY PRINT FOR DEBUG COMPILE";
DLOG_IF_EVERY_N(INFO,true,1)<<"ONLY PRINT FOR DEBUG COMPILE";

void GoogleVLogTest(int v)
{
fLI::FLAGS_v = v;
VLOG(1)<<"if FLAGS_v >1, printf info";
VLOG(3)<<"IF FLAGS_v > 3,printf info";

//VLOG_IF
//VLOG_EVERY_N
//VLOG_IF_EVERY_N
//DVLOG
//DVLOG_IF
}


免責聲明!

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



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