Google glog是一个实现应用程序级日志记录的库。这个库提供了基于C ++风格的流和各种帮助宏的日志API。您可以通过简单地将内容流式传输到LOG(\
一、安全级别
可以指定以下安全级别之一(按严重性的升序排列):INFO,WARNING,ERROR和FATAL。记录FATAL消息终止程序(记录消息之后)。请注意,给定严重性的消息不仅记录在该严重性的日志文件中,还记录在严重性较低的所有日志文件中。例如,严重性为FATAL的消息将被记录到严重性为FATAL,ERROR,WARNING和INFO的日志文件中。
在调试模式(没有定义NDEBUG宏),DFATAL通过自动将安装性降低到ERROR来避免停止进行中的程序。
除非特别指定,那么glog写入文件名“/tmp/\.\\.log.\.\.\
二、设置标志
几个标志影响glog的输出行为。如果您的计算机上安装了Google gflags库,则配置脚本(请参阅包中的INSTALL文件以获取此脚本的详细信息)将自动检测并使用它,从而允许您在命令行上传递标志。例如,如果要打开–logtostderr标志,可以使用以下命令行启动应用程序:
./your_application --logtostderr=1
如果没有安装Google gflags库,您可以通过环境变量来设置标志,在标志名前添加“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)
记录消息等于或高于此级别。同样,安全性级别INFO,WARNING,ERROR和FATAL的数量分别为0,1,2和3。log_dir(string,default =“”)
如果指定,则将日志文件写入此目录而不是默认日志记录目录。vmodule(string,default =“”)
Per-module verbose level. The argument has to contain a comma-separated list of =. is a glob pattern (e.g., gfs* for all modules whose name starts with “gfs”), matched against the filename base (that is, name ignoring .cc/.h./-inl.h). overrides any value given by –v. See also the section about verbose logging.
可以通过修改全局变量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”;
只有当变量num_cookies超过10时,才会记录“Got lots of cookies”的消息。如果一行代码被执行很多次,那么以特定间隔记录消息可能是有用的。这种日志记录对于信息消息是最有用的。
LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
上面的代码只有在1st, 11th, 21st, …次执行时, 才输出消息。请注意,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 cookie";
五、CHECK宏标志
检查程序中的预期条件来尽早检测错误是一种很好的做法。 CHECK宏提供了在条件不满足时中止应用程序的能力,类似于标准C库中定义的assert宏。
如果条件不正确,CHECK会中止应用程序。与assert不同的是,它不受NDEBUG控制,所以无论编译模式如何,都会执行检查。因此,以下示例中的fp->Write(x)总是执行:
CHECK(fp->Write(x) == 4) << "Write failed!";
用于相等/不等式检查的各种宏 - CHECK_EQ,CHECK_NE,CHECK_LE,CHECK_LT,CHECK_GE和CHECK_GT。它们比较两个值,并在结果不符合预期时记录包含这两个值的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记录自定义消息。
如果比较C字符串(char *),则一组宏将执行区分大小写以及不区分大小写的比较- CHECK_STREQ,CHECK_STRNE,CHECK_STRCASEEQ和CHECK_STRCASENE。 CASE版本不区分大小写。您可以安全地传递此宏的NULL指针。它们将NULL和任何非NULL字符串视为不相等。两个NULL是相等的。
请注意,这两个参数可能是临时字符串(例如CHECK_STREQ(Foo().c_str(),Bar().c_str()),其中Foo和Bar返回C ++的std::string)。
CHECK_DOUBLE_EQ宏检查两个浮点值的相等性,接受一个小的误差。 CHECK_NEAR接受第三个浮点参数,它指定可接受的误差范围。
六、详细记录
当寻找困难的错误,详细的日志消息是非常有用的。但是,在平常的开发中,您可能会忽略太冗长的消息。对于这样详细的日志记录,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,详细级别越低,消息被记录的可能性就越大。例如,如果–v == 1,VLOG(1)将会记录,但VLOG(2)将不记录。这与安全级别相反,其中INFO为0,ERROR为2. –minloglevel为1将记录WARNING及以上。虽然您可以为VLOG宏和–v标志指定任何整数,但它们的常用值是小正整数。例如,如果写了VLOG(0),你应该指定–v = -1或更低来使其静音。这是不太有用的,因为在大多数情况下我们可能不需要默认的详细日志。 VLOG宏总是在INFO日志级别时候记录。
详细日志记录可以从每个模块的命令行进行控制:
--vmodule=mapreduce=2,file=1,gfs*=3 --v=0
- Print VLOG(2) and lower messages from mapreduce.{h,cc}
- Print VLOG(1) and lower messages from file.{h,cc}
- Print VLOG(3) and lower messages from files prefixed with “gfs”
- Print VLOG(0) and lower messages from elsewhere
(3)所示的通配符功能支持“*”(匹配0个或多个字符)和’?’ (匹配任何单个字符)通配符。
还有VLOG_IS_ON(n)“详细级别”条件宏。当 -v等于或大于n时,此宏返回true。
if (VLOG_IS_ON(2)) {
// do some logging preparation and logging
// that can't be accomplished with just VLOG(2) << ...;
}
详细级别条件宏VLOG_IF,VLOG_EVERY_N和VLOG_IF_EVERY_N的行为类似于LOG_IF,LOG_EVERY_N,LOF_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;