google glog 是一个提供应用层日志接口的库。这个库提供了基于C++风格的数据流和大量有帮助的宏命令。
你可以记录一个信息通过简单的数据流日志。
#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";
}
glog定义了一系列宏来简化常用的日志任务。你可以根据严重程度来记录日志,通过命令行来控制日志,日志基于条件,当条件不满足时中断程序,导入你自己详细的日志级别等等。这个文件描述了glog所支持的功能。请注意这个文档没有描述库中所有的功能,但是是最常用的。如果你要使用一些不常用的功能,请检查在src/glog目录下的头文件。
您可以指定下列严重性级别之一(严重程度的增加顺序): INFO,WARNING ,ERROR和FATAL 。记录一个FATAL消息终止程序(被记录的消息后)。注意,高严重级别的信息不但记录在当前日志,而且在低级别的所有日志文件。例如,严重性FATAL的消息将被记录到的严重性是FATAL,ERROR,WARNING,INFO的日志文件。
一些标志影响glog的输出行为。如果Google gflags 库已经安装在你的机器上,那么配置文件会自动检测和使用,允许你通过命令行来设置标志。
例如,如果你要把–logtosrderr标志打开,你可以通过以下命令来开始你的应用。
./your_application --logtostderr=1
如果google gflags库没有安装,你可以通过环境变量来设置标记,标志名的前缀是”GLOG_”
GLOG_logtostderr=1 ./your_application
以下的标志是最常用的:
logtostderr (bool, default=false)
日志信息输出到标准错误输出而不是日志文件。注意:false可以用0代替,true可以用1代替。
stderrthreshold (int, default=2, which is ERROR)
复制这个级别或者更高级的日志信息到标准错误输出而不是日志文件。后面的数字代表级别:按严重级别依次是0,1,2,3。
minloglevel (int, default=0, which is INFO)
记录信息的最低级别。数字和上面意义一样。
log_dir (string, default="")
保存日志文件。
v (int, default=0)
显示所有这个级别以内的日志信息。
vmodule (string, default="")
每个模块的详细级别。参数必须包含一个逗号分隔的列表<模块名><日志级别>。
还有一些别的标志在logging.cc中定义。可以在源代码中搜索“ DEFINE_ ”就能看到所有标志的完整列表。
您也可以通过在自己程序中修改全局变量FLAGS * 来修改标志值。多数设置在你修改后FLAGS _* 立即开始作用 。例外的是有关目的地文件的标志。例如,您可能需要设置FLAGS log _ dir 在调用google:: InitGoogleLogging之前。下面是一个例子:
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_EVERY _ N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
上面这个命令是每隔十次输出一个日志信息。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次执行后的日志信息。
“Debug mode”下的宏命令只在debug模式中有效和被编译,对非debug模式无效而且不会编译。通过使用这些宏命令来避免因为过多的日志信息而减慢应用的开发。
这是一个很好的做法,检查程序预计情况经常为尽早发现错误。检查宏提供中止该应用程序时,一个条件不满足,类似于标准C库定义的断言宏的能力。
CHECK在条件不成立时终止应用。不像assert,不会被NDEBUG控制,所以检查时将忽略编译模式执行。因此,fp->Write(x)在下面的例子中会被执行:
CHECK(fp->Write(x) == 4) << "Write failed!";
用很多宏命令来判断是否相等。它们比较两个值然后记录一个FATAL信息包括这两个值并不如预期的结果时。这个值必须要operator<<(ostream, …)来定义。
你可以像这样添加一个错误信息:
CHECK_NE(1, 2) << ": The world 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。
如果你要比较字符串,可以用CHECK_STREQ,CHECK_STRNE,CHECK_STRCASEEQ,CHECK_STRCASENE。对于NULL指针你可以使用以上命令,它们对于NULL和non-NULL是不相等的。
CHECK_DOUBLE_EQ检测两个浮点数是否相等
当你找一些复杂的BUG,这些日志信息就很有帮助了。你可能希望忽略一些冗余信息。对于这种情况glog提供了VLOG命令来让你自己定义你希望记录的日志级别。VLOG(N)会记录N级以上的日志信息。
--vmodule=mapreduce=2,file=1,gfs*=3,--v=0
上面命令相当于VLOG(2)mapreduce.{cc,h},VLOG(1)file.{cc,h},VLOG(3)gfs前缀的cc,h,其余文件VLOG(0)。
冗余级别条件判断VLOG_IF,VLOG_EVERY_N,VLOG_IF_EVERY_N。
失败信号句柄
库提供了很方便的信号句柄来记录信息当程序崩溃的时候。由google::InstallFailureSignalHandler()来初始化。