glog是什么意思,glog簡介

 2023-12-25 阅读 33 评论 0

摘要:引言 原文英文鏈接.翻譯中有一些個人添加的輔助信息,以括號標識,”注:”開頭,以粗體表示,例如(注:以下為個人翻譯,水平有限,歡迎指正). Google glog是一個應用級別的日志系統庫.它提供基于C++風格的流和各種輔助宏的日志API.你可以使用LOG(<特定等級>)輸出日志信

引言

原文英文鏈接.翻譯中有一些個人添加的輔助信息,以括號標識,”注:”開頭,以粗體表示,例如(注:以下為個人翻譯,水平有限,歡迎指正).
Google glog是一個應用級別的日志系統庫.它提供基于C++風格的流和各種輔助宏的日志API.你可以使用LOG(<特定等級>)輸出日志信息信息,例如:

#include <glog/logging.h>int main(int argc, char* argv[]) {// Initialize Google's logging library.google::InitGoogleLogging(argv[0]);// ...LOG(INFO) << "Found " << num_cookies << " cookies";
}

Google glog定義了一系列的宏簡化的常用的日志任務.你可以輸出不同嚴重等級的日志信息,通過命令行控制日志的行為,基于特定條件的日志輸出,當期望的條件沒有觸發時中止程序運行,引入你自己的更多的日志等級等等.這個文檔介紹glog所支持的功能.這個文檔并不能描述glog庫的所有功能,僅是最有用的部分.如果你希望看到一些不常用的功能,請查閱src/glog文件夾里的頭文件.
- google-glog
- Github:glog

嚴重性等級

你可以指定以下嚴重性等級中的一個(嚴重性從低到高):INFO,WARNING,ERROR,FATAL.輸出一個FATAL信息會中止程序(在這條信息輸出之后中止).注意:一個特定嚴重等級的日志信息不僅僅輸出到該嚴重等級的日志文件中,它還會被記錄到比它嚴重等級更低的文件中.例如,一個嚴重等級為FATAL的日志信息將會被記錄到嚴重等級為FATAL,ERROR,WARNING,INFO的所有文件中.
DFATAL在debug模式下是一個FATAL等級的日志輸出(例如,沒有NDEBUG宏定義),為了避免軟件在發布后被停止運行,嚴重等級會自動的被降低到 ERROR.
除非另有指定,glog默認將日志寫入:

/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>

(例如,”/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474”).glog默認會將嚴重等級為ERRORFATAL的日志信息除了輸出到日志文件中,還會輸出到標準錯誤中(stderr).

設置標志

一些標志影響glog的輸出行為.如果Google gflags library已經安裝到你的電腦上,configure腳本(查看在包中的INSTALL文件,有詳細的腳本)將自動的檢測并使用它,同時允許通過命令行傳遞標志.例如,如果你希望打開–logtostderr標志,你可以使用下面的命令行啟動應用程序:

   ./your_application --logtostderr=1

glog是什么意思、如果你并未安裝Google flags library,你可以通過環境變量設置標志,以’GLOG_’作為標志名的前綴,例如:

   GLOG_logtostderr=1 ./your_application

以下是常用的標志:
logtostderr (bool,default=false)
日志信息將不會輸出到日志文件中,而是輸出到stderr.
注:你可以通過指定為1,true,yes(大小寫敏感),設置標志為true. 你可以指定為0,false,no(大小寫敏感)設置標志為false.
stderrthreshold(int, default=2, which is ERROR)
將大于嚴重等級閥值日志信息除了輸出到日志文件中,還會輸出到stderr中.嚴重等級INFO,WARNING,ERROR,FATAL分別對應0,1,2,3.
minloglevel (int, default=0, which is INFO)
大于或等于這個等級的日志將會被打印出來.
log_dir (string, default=”“)
設置日志指定的日志文件夾.
v (int, default=0)
顯示所有VLOG(m)小于或等于這個標志’m’的信息.可以用–vmodule代替.詳細見verbose logging.
vmodule (string, default=”“)
每個模塊的verbose等級.這個參數會在有系列逗號分別的列表中,=.是全局(例如gfs*表示gfs開頭的所有模塊).可以通過’–v’.詳細見the section about verbose logging.
還有許多其他的標志定義在logging.cc中.請使用grep(linux里的grep命令,windows上就自己搜索下)搜索源碼查看所有的標志,這些標志位定義以’DEFINE_’開頭.
你還可以通過在程序中修改全局變量FLAGS_*來修改標志.當你更新完FLAGS_*變量后,絕大多數的設置會立即生效.與目標文件相關的標志是另外,你需要在調用google::InitGoogleLogging之前設置FLAGS_log_dir.以下是一個例子:

LOG(INFO) << "file";
// Most flags work immediately after updating values.
FLAGS_logtostderr = 1;
LOG(INFO) << "stderr";
FLAGS_logtostderr = 0;
// This won't change the log destination. If you want to set this
// value, you should do this before google::InitGoogleLogging .
FLAGS_log_dir = "/some/log/directory";
LOG(INFO) << "the same file";

條件型/特殊情況型日志

有時,你只希望在特定的情況下輸出日志.你可以使用一下的宏來執行條件日志:

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

“Got lots of cookies”信息只有在變量num_cookies大于10時才會被打印.如果一段代碼被多次執行,按照一定的間隔來輸出日志信息是有用的(否則每次都執行,log量很大不便分析),可以按如下方式打印:

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

上面的代碼會在第一次,第11次,第21次,…執行時被打印出來.注意:google::COUNTER值用來標識重復的次數.
你可以使用如下的宏來組合條件型和特殊情況型日志:

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

與每執行N次打印一次相比,你可以限定第N次執行時打印一次,:

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

當這個代碼第一次被執行20次后,這個打印會被輸出.google::COUNTER標識已經重復的次數.

支持調試模式

“調試模式”日志宏只在調試模式下才生效,非調試模式下不起作用.可以使用這些宏來避免執行不必要的日志從而拖慢你的應用.

DLOG(INFO) << "Found cookies";
DLOG_IF(INFO, num_cookies > 10)  << "Got lots of cookies";
DLOG_EVERY_N(INFO,10) << "Got the " << google::COUNTER << "th cooike";

CHECK宏

在你的程序中經常檢測預期的條件者是一個很好的做法,它能夠盡早的發現錯誤.CHECK宏提供了這種功能,當條件不滿足時將會中止應用程序,這類似于標準C庫里定義的assert宏.
如果條件不滿足CHECK中止應用程序,它不受控于NDEBUG,CHECK將無視編譯模式(不論是調試模式,還是正常模式,CHECK都會起作用),因此,fp->Write(x)永遠都會被執行:

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

有許多幫助宏來表示相等或不等的情況-CHECK_EQ,CHECK_NE,CHECK_LE,CHECK_LT,CHECK_GE以及CHECK_GT.他們比較2個值的情況,當結果不是所期望的情況下會輸出FATAL日志信息,這個信息包含這2個值,這些值必須定義operator<<(ostream,…).
你可能添加錯誤信息如下:

CHECK_NE(1,2) << ": The wrold must be ending!";

我們非常小心的評估每個參數,任何一個合法的函數參數形式在這里都是合法的.特別的,參數可能是臨時的表達式,它將在聲明的作用域之外被銷毀,例如:

CHECK_EQ(string("abc")[1],'b');

如果其中一個參數是指針,另外一個是NULL編譯器會報錯.為了解決這個問題,可以用static_cast NULL來指定該空指針:

CHECK_EQ(some_ptr, static_cast<SomeType *>(NULL));

使用CHECK_NOTNULL宏會更好:

CHECK_NOTNULL(some_ptr);
some_ptr->DoSomething();

因為這個宏返回一個指針,這個在構造函數初始化列表中非常有用.

struct s{S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)){};Something* ptr_;
}

注意你不能使用這個宏處理C++流.請使用上面的CHECK_EQ來操作C++流.
如果你比較C字符串(char ),有一套宏來執行比較,這套宏可以區分/不區分大小寫-*CHECK_STREQ,CHECK_STRNE,CHECK_STRCASEEQ,CHECK_STRCASENE.CASE版本是不區分大小寫的.這幾個宏使用中你可以安全的傳遞NULL指針.NULL指針是非NULL指針總是不相等的.兩個NULL指針是相等的.
注意2個參數可能是臨時字符串,它們在表達式之后就會被銷毀.
CHECK_DOUBLE_EQ宏檢測兩個浮點數的值是否相等,誤差很小(0.000000000000001L).CHECK_NEAR可以設置誤差的大小(CHECK_DOUBLE_EQ的擴展版本,看一下源碼定義就知道了).

Verbose日志

當你在處理困難的bug時,詳盡的日志信息是非常有幫助的.但是你希望忽略一些冗長的信息.為了這樣的verbose日志,glog提供VLOG宏,它允許你定義你自己的日志等級.–v命令行參數控制那些日志將被打印:

VLOG(1) << "I'm printed when you run the program with --v=1 or higher";
VLOG(2) << "I'm printed when you run the program with --v=2 or higher";

VLOG中,verbose等級越低,越有可能被打印出來.例如,如果–v=1,VLOG(1)將會輸出日志,VLOG(2)不會輸出日志.這個與之前的嚴重等級相反,嚴重等級中INFO是0,ERROR是2.–minloglevel如果是1,那么WARNING以及以上的嚴重等級會被輸出.雖然你可以為VLOG和–v標志指定任何的整數,但通常指定為比較小的正整數.例如,如果你代碼寫了VLOG(0),你應該指定–v=-1或更小的值才能使它不被打印.在多數情況下我們不會這么設置verbose日志.VLOG宏總是以INFO等級的log輸出.
Verbose日志通過命令行來指定每個模塊的日志控制情況:

--vmodule=mapreduce=2,file=1,gfs*=3 --v=0

表示:

  • a. 在mapreduce中打印VLOG(2) 和更低等級的信息.
  • b. 在file中打印VLOG(1)和等級更低的信息.
  • c. 在以’gfs’為前綴的文件中打印VLOG(3)和等級更低的信息.
  • d. 在其他地方打印VLOG(0)和等級更低的信息.
    命令行中支持通配符’*’(表示0個或多個單詞)以及’?’(匹配任何一個單詞).詳細見command line flags.
    還有”verbose”等級控制宏VLOG_IS_ON(n).當–v和n相等或比n更大時,宏返回true,如下所示:
if(VLOG_IS_ON(2)){//do some logging preparation and logging//that can't accomplished with just LOG(2) << ...;
}

Verbose等級條件宏VLOG_IF,VLOG_EVERY_N,VLOG_IF_EVERY_N,行為類似于LOG_IF,LOG_EVERY_N,LOG_IF_EVERY,接收的數字參數的控制含義與嚴重等級相反.

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";
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 " << google::COUNTER;
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 " << google::COUNTER;

異常信號處理

glog提供了方便的信號處理機制,如果程序崩潰發送信號SIGSEGV時可以導出非常有用的信息.信號處理可以調用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)

默認情況下,信號處理導出標準錯誤信息.如果你希望定制,則需要了解InstallFailureWriter().

其他信息

消息性能

glog提供的條件型日志宏(例如:CHECK,LOG_IF,VLOG,…)被小心的實現著以便當條件不滿足時,右邊的表達式不會被執行.所以如下的CHECK不會影響你的應用的性能(obj.ok為false,后面不會被執行):

CHECK(obj.ok) << obj.CreatePrettyFormattedStringBufVerySlow();

用戶自定義的異常函數

嚴重等級為FATAL的信息或是不滿足CHECK的條件,你的程序將會被中止.你可以通過使用InstallFailureFunction來代替中止的行為.

void YourFailureFunction() {// Reports something...exit(1);
}int main(int argc, char* argv[]) {google::InstallFailureFunction(&YourFailureFunction);
}

默認情況下,glog盡力導出堆棧信息,并且讓應用程序返回狀態1.堆棧追蹤信息只在已經支持的平臺上實現(2008年9月,glog支持x86和x86_64).

原日志

頭文件

Google風格的perror()

PLOG(),PLOG_IF()PCHECK()的作用與LOG,CHECK,相似,它附帶了errorno的信息.例如:

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

如果上面的PCHECK的表達式為表達式為false,那么會有如下的錯誤信息:

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

SYSLOG

SYSLOG,SYSLOG_IF,SYSLOG_EVERY_N宏都是有效的.這些日志除了正常的日志外,還會寫入系統日志中.注意記錄到syslog可能會影響性能,特別是當它配置為遠程日志時!確保你在使用系統日志時候,你對它們是非常了解的.通常情況下,盡量少用這些是明智的.

精簡日志信息

日志中包含大量的字符串會增加二進制文件的大小,同時會暴露隱私問題.你可以使用GOOGLE_STRIP_LOG宏來移除哪些嚴重等級小于特定等級的日志:
如果你的應用程序代碼如下:

#define GOOGLE_STRIP_LOG 1   //this must go before the #include!
#include <glog/logging.h>

編譯器將會移除嚴重程度低于指定級別的日志.因為VLOG日志處于嚴重等級的INFO等級(即0),設置GOOGLE_STRIP_LOG為1或更大的值,將移除與VLOG相關的日志信息,當然也包括INFO指定的日志信息.

windows用戶注意事項

Google glog定義了ERROR的嚴重等級,它也被定義在windows.h中.你可以在glog/logging.h之前定義GLOG_NO_ABBREVIATED_SEVERITIES來使glog不對INFO,WARNING,ERROR,FATAL定義,定義了這個宏之后,你仍然可以使用iostream日志工具:

#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <windows.h>
#include <glog/logging.h>
//...
LOG(ERROR) << "this should work";
LOG_IF(ERROR,x > y) << "This should be also OK";

但是,你不能使用INFO,WARNING,ERROR,FATAL這些已經在glog/logging.h中定義的。

#define GLOG_NO_ABBREVIATED_SEVERITIES
#include <windows.h>
#include <glog/logging.h>
//...//This won't work.
//google::FlushLogFiles(google::ERROR);//Use this instead.
google::FlushLogFiles(google::GLOG_ERROR);

如果你 不想用windows.h中定義的ERROR:

  • 在”#include < windows.h >”之前”#define WIN32_LEAN_AND_MEAN”或”#define NOGDI”.
  • 在”#include < windows.h >”之后”#undef ERROR”.

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/196789.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息