michael@0: michael@0: michael@0: michael@0: michael@0: How To Use Google Logging Library (glog) michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0:

How To Use Google Logging Library (glog)

michael@0: (as of michael@0: ) michael@0: michael@0:
michael@0: michael@0:

Introduction

michael@0: michael@0:

Google glog is a library that implements application-level michael@0: logging. This library provides logging APIs based on C++-style michael@0: streams and various helper macros. michael@0: You can log a message by simply streaming things to LOG(<a michael@0: particular severity level>), e.g. michael@0: michael@0:

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

Google glog defines a series of macros that simplify many common logging michael@0: tasks. You can log messages by severity level, control logging michael@0: behavior from the command line, log based on conditionals, abort the michael@0: program when expected conditions are not met, introduce your own michael@0: verbose logging levels, and more. This document describes the michael@0: functionality supported by glog. Please note that this document michael@0: doesn't describe all features in this library, but the most useful michael@0: ones. If you want to find less common features, please check michael@0: header files under src/glog directory. michael@0: michael@0:

Severity Level

michael@0: michael@0:

michael@0: You can specify one of the following severity levels (in michael@0: increasing order of severity): INFO, WARNING, michael@0: ERROR, and FATAL. michael@0: Logging a FATAL message terminates the program (after the michael@0: message is logged). michael@0: Note that messages of a given severity are logged not only in the michael@0: logfile for that severity, but also in all logfiles of lower severity. michael@0: E.g., a message of severity FATAL will be logged to the michael@0: logfiles of severity FATAL, ERROR, michael@0: WARNING, and INFO. michael@0: michael@0:

michael@0: The DFATAL severity logs a FATAL error in michael@0: debug mode (i.e., there is no NDEBUG macro defined), but michael@0: avoids halting the program in production by automatically reducing the michael@0: severity to ERROR. michael@0: michael@0:

Unless otherwise specified, glog writes to the filename michael@0: "/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>" michael@0: (e.g., "/tmp/hello_world.example.com.hamaji.log.INFO.20080709-222411.10474"). michael@0: By default, glog copies the log messages of severity level michael@0: ERROR or FATAL to standard error (stderr) michael@0: in addition to log files. michael@0: michael@0:

Setting Flags

michael@0: michael@0:

Several flags influence glog's output behavior. michael@0: If the Google michael@0: gflags library is installed on your machine, the michael@0: configure script (see the INSTALL file in the package for michael@0: detail of this script) will automatically detect and use it, michael@0: allowing you to pass flags on the command line. For example, if you michael@0: want to turn the flag --logtostderr on, you can start michael@0: your application with the following command line: michael@0: michael@0:

michael@0:    ./your_application --logtostderr=1
michael@0: 
michael@0: michael@0: If the Google gflags library isn't installed, you set flags via michael@0: environment variables, prefixing the flag name with "GLOG_", e.g. michael@0: michael@0:
michael@0:    GLOG_logtostderr=1 ./your_application
michael@0: 
michael@0: michael@0: michael@0: michael@0:

The following flags are most commonly used: michael@0: michael@0:

michael@0:
logtostderr (bool, default=false) michael@0:
Log messages to stderr instead of logfiles.
michael@0: Note: you can set binary flags to true by specifying michael@0: 1, true, or yes (case michael@0: insensitive). michael@0: Also, you can set binary flags to false by specifying michael@0: 0, false, or no (again, case michael@0: insensitive). michael@0:
stderrthreshold (int, default=2, which michael@0: is ERROR) michael@0:
Copy log messages at or above this level to stderr in michael@0: addition to logfiles. The numbers of severity levels michael@0: INFO, WARNING, ERROR, and michael@0: FATAL are 0, 1, 2, and 3, respectively. michael@0:
minloglevel (int, default=0, which michael@0: is INFO) michael@0:
Log messages at or above this level. Again, the numbers of michael@0: severity levels INFO, WARNING, michael@0: ERROR, and FATAL are 0, 1, 2, and 3, michael@0: respectively. michael@0:
log_dir (string, default="") michael@0:
If specified, logfiles are written into this directory instead michael@0: of the default logging directory. michael@0:
v (int, default=0) michael@0:
Show all VLOG(m) messages for m less or michael@0: equal the value of this flag. Overridable by --vmodule. michael@0: See the section about verbose logging for more michael@0: detail. michael@0:
vmodule (string, default="") michael@0:
Per-module verbose level. The argument has to contain a michael@0: comma-separated list of <module name>=<log level>. michael@0: <module name> michael@0: is a glob pattern (e.g., gfs* for all modules whose name michael@0: starts with "gfs"), matched against the filename base michael@0: (that is, name ignoring .cc/.h./-inl.h). michael@0: <log level> overrides any value given by --v. michael@0: See also the section about verbose logging. michael@0:
michael@0: michael@0:

There are some other flags defined in logging.cc. Please grep the michael@0: source code for "DEFINE_" to see a complete list of all flags. michael@0: michael@0:

Conditional / Occasional Logging

michael@0: michael@0:

Sometimes, you may only want to log a message under certain michael@0: conditions. You can use the following macros to perform conditional michael@0: logging: michael@0: michael@0:

michael@0:    LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
michael@0: 
michael@0: michael@0: The "Got lots of cookies" message is logged only when the variable michael@0: num_cookies exceeds 10. michael@0: michael@0: If a line of code is executed many times, it may be useful to only log michael@0: a message at certain intervals. This kind of logging is most useful michael@0: for informational messages. michael@0: michael@0:
michael@0:    LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th cookie";
michael@0: 
michael@0: michael@0:

The above line outputs a log messages on the 1st, 11th, michael@0: 21st, ... times it is executed. Note that the special michael@0: google::COUNTER value is used to identify which repetition is michael@0: happening. michael@0: michael@0:

You can combine conditional and occasional logging with the michael@0: following macro. michael@0: michael@0:

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

Instead of outputting a message every nth time, you can also limit michael@0: the output to the first n occurrences: michael@0: michael@0:

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

Outputs log messages for the first 20 times it is executed. Again, michael@0: the google::COUNTER identifier indicates which repetition is michael@0: happening. michael@0: michael@0:

Debug Mode Support

michael@0: michael@0:

Special "debug mode" logging macros only have an effect in debug michael@0: mode and are compiled away to nothing for non-debug mode michael@0: compiles. Use these macros to avoid slowing down your production michael@0: application due to excessive logging. michael@0: michael@0:

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

CHECK Macros

michael@0: michael@0:

It is a good practice to check expected conditions in your program michael@0: frequently to detect errors as early as possible. The michael@0: CHECK macro provides the ability to abort the application michael@0: when a condition is not met, similar to the assert macro michael@0: defined in the standard C library. michael@0: michael@0:

CHECK aborts the application if a condition is not michael@0: true. Unlike assert, it is *not* controlled by michael@0: NDEBUG, so the check will be executed regardless of michael@0: compilation mode. Therefore, fp->Write(x) in the michael@0: following example is always executed: michael@0: michael@0:

michael@0:    CHECK(fp->Write(x) == 4) << "Write failed!";
michael@0: 
michael@0: michael@0:

There are various helper macros for michael@0: equality/inequality checks - CHECK_EQ, michael@0: CHECK_NE, CHECK_LE, CHECK_LT, michael@0: CHECK_GE, and CHECK_GT. michael@0: They compare two values, and log a michael@0: FATAL message including the two values when the result is michael@0: not as expected. The values must have operator<<(ostream, michael@0: ...) defined. michael@0: michael@0:

You may append to the error message like so: michael@0: michael@0:

michael@0:    CHECK_NE(1, 2) << ": The world must be ending!";
michael@0: 
michael@0: michael@0:

We are very careful to ensure that each argument is evaluated exactly michael@0: once, and that anything which is legal to pass as a function argument is michael@0: legal here. In particular, the arguments may be temporary expressions michael@0: which will end up being destroyed at the end of the apparent statement, michael@0: for example: michael@0: michael@0:

michael@0:    CHECK_EQ(string("abc")[1], 'b');
michael@0: 
michael@0: michael@0:

The compiler reports an error if one of the arguments is a michael@0: pointer and the other is NULL. To work around this, simply static_cast michael@0: NULL to the type of the desired pointer. michael@0: michael@0:

michael@0:    CHECK_EQ(some_ptr, static_cast<SomeType*>(NULL));
michael@0: 
michael@0: michael@0:

Better yet, use the CHECK_NOTNULL macro: michael@0: michael@0:

michael@0:    CHECK_NOTNULL(some_ptr);
michael@0:    some_ptr->DoSomething();
michael@0: 
michael@0: michael@0:

Since this macro returns the given pointer, this is very useful in michael@0: constructor initializer lists. michael@0: michael@0:

michael@0:    struct S {
michael@0:      S(Something* ptr) : ptr_(CHECK_NOTNULL(ptr)) {}
michael@0:      Something* ptr_;
michael@0:    };
michael@0: 
michael@0: michael@0:

Note that you cannot use this macro as a C++ stream due to this michael@0: feature. Please use CHECK_EQ described above to log a michael@0: custom message before aborting the application. michael@0: michael@0:

If you are comparing C strings (char *), a handy set of macros michael@0: performs case sensitive as well as case insensitive comparisons - michael@0: CHECK_STREQ, CHECK_STRNE, michael@0: CHECK_STRCASEEQ, and CHECK_STRCASENE. The michael@0: CASE versions are case-insensitive. You can safely pass NULL michael@0: pointers for this macro. They treat NULL and any michael@0: non-NULL string as not equal. Two NULLs are michael@0: equal. michael@0: michael@0:

Note that both arguments may be temporary strings which are michael@0: destructed at the end of the current "full expression" michael@0: (e.g., CHECK_STREQ(Foo().c_str(), Bar().c_str()) where michael@0: Foo and Bar return C++'s michael@0: std::string). michael@0: michael@0:

The CHECK_DOUBLE_EQ macro checks the equality of two michael@0: floating point values, accepting a small error margin. michael@0: CHECK_NEAR accepts a third floating point argument, which michael@0: specifies the acceptable error margin. michael@0: michael@0:

Verbose Logging

michael@0: michael@0:

When you are chasing difficult bugs, thorough log messages are very michael@0: useful. However, you may want to ignore too verbose messages in usual michael@0: development. For such verbose logging, glog provides the michael@0: VLOG macro, which allows you to define your own numeric michael@0: logging levels. The --v command line option controls michael@0: which verbose messages are logged: michael@0: michael@0:

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

With VLOG, the lower the verbose level, the more michael@0: likely messages are to be logged. For example, if michael@0: --v==1, VLOG(1) will log, but michael@0: VLOG(2) will not log. This is opposite of the severity michael@0: level, where INFO is 0, and ERROR is 2. michael@0: --minloglevel of 1 will log WARNING and michael@0: above. Though you can specify any integers for both VLOG michael@0: macro and --v flag, the common values for them are small michael@0: positive integers. For example, if you write VLOG(0), michael@0: you should specify --v=-1 or lower to silence it. This michael@0: is less useful since we may not want verbose logs by default in most michael@0: cases. The VLOG macros always log at the michael@0: INFO log level (when they log at all). michael@0: michael@0:

Verbose logging can be controlled from the command line on a michael@0: per-module basis: michael@0: michael@0:

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

will: michael@0: michael@0:

michael@0: michael@0:

The wildcarding functionality shown by (c) supports both '*' michael@0: (matches 0 or more characters) and '?' (matches any single character) michael@0: wildcards. Please also check the section about command line flags. michael@0: michael@0:

There's also VLOG_IS_ON(n) "verbose level" condition michael@0: macro. This macro returns true when the --v is equal or michael@0: greater than n. To be used as michael@0: michael@0:

michael@0:    if (VLOG_IS_ON(2)) {
michael@0:      // do some logging preparation and logging
michael@0:      // that can't be accomplished with just VLOG(2) << ...;
michael@0:    }
michael@0: 
michael@0: michael@0:

Verbose level condition macros VLOG_IF, michael@0: VLOG_EVERY_N and VLOG_IF_EVERY_N behave michael@0: analogous to LOG_IF, LOG_EVERY_N, michael@0: LOF_IF_EVERY, but accept a numeric verbosity level as michael@0: opposed to a severity level. michael@0: michael@0:

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

Failure Signal Handler

michael@0: michael@0:

michael@0: The library provides a convenient signal handler that will dump useful michael@0: information when the program crashes on certain signals such as SIGSEGV. michael@0: The signal handler can be installed by michael@0: google::InstallFailureSignalHandler(). The following is an example of output michael@0: from the signal handler. michael@0: michael@0:

michael@0: *** Aborted at 1225095260 (unix time) try "date -d @1225095260" if you are using GNU date ***
michael@0: *** SIGSEGV (@0x0) received by PID 17711 (TID 0x7f893090a6f0) from PID 0; stack trace: ***
michael@0: PC: @           0x412eb1 TestWaitingLogSink::send()
michael@0:     @     0x7f892fb417d0 (unknown)
michael@0:     @           0x412eb1 TestWaitingLogSink::send()
michael@0:     @     0x7f89304f7f06 google::LogMessage::SendToLog()
michael@0:     @     0x7f89304f35af google::LogMessage::Flush()
michael@0:     @     0x7f89304f3739 google::LogMessage::~LogMessage()
michael@0:     @           0x408cf4 TestLogSinkWaitTillSent()
michael@0:     @           0x4115de main
michael@0:     @     0x7f892f7ef1c4 (unknown)
michael@0:     @           0x4046f9 (unknown)
michael@0: 
michael@0: michael@0:

michael@0: By default, the signal handler writes the failure dump to the standard michael@0: error. You can customize the destination by InstallFailureWriter(). michael@0: michael@0:

Miscellaneous Notes

michael@0: michael@0:

Performance of Messages

michael@0: michael@0:

The conditional logging macros provided by glog (e.g., michael@0: CHECK, LOG_IF, VLOG, ...) are michael@0: carefully implemented and don't execute the right hand side michael@0: expressions when the conditions are false. So, the following check michael@0: may not sacrifice the performance of your application. michael@0: michael@0:

michael@0:    CHECK(obj.ok) << obj.CreatePrettyFormattedStringButVerySlow();
michael@0: 
michael@0: michael@0:

User-defined Failure Function

michael@0: michael@0:

FATAL severity level messages or unsatisfied michael@0: CHECK condition terminate your program. You can change michael@0: the behavior of the termination by michael@0: InstallFailureFunction. michael@0: michael@0:

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

By default, glog tries to dump stacktrace and makes the program michael@0: exit with status 1. The stacktrace is produced only when you run the michael@0: program on an architecture for which glog supports stack tracing (as michael@0: of September 2008, glog supports stack tracing for x86 and x86_64). michael@0: michael@0:

Raw Logging

michael@0: michael@0:

The header file <glog/raw_logging.h> can be michael@0: used for thread-safe logging, which does not allocate any memory or michael@0: acquire any locks. Therefore, the macros defined in this michael@0: header file can be used by low-level memory allocation and michael@0: synchronization code. michael@0: Please check src/glog/raw_logging.h.in for detail. michael@0:

michael@0: michael@0:

Google Style perror()

michael@0: michael@0:

PLOG() and PLOG_IF() and michael@0: PCHECK() behave exactly like their LOG* and michael@0: CHECK equivalents with the addition that they append a michael@0: description of the current state of errno to their output lines. michael@0: E.g. michael@0: michael@0:

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

This check fails with the following error message. michael@0: michael@0:

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

Syslog

michael@0: michael@0:

SYSLOG, SYSLOG_IF, and michael@0: SYSLOG_EVERY_N macros are available. michael@0: These log to syslog in addition to the normal logs. Be aware that michael@0: logging to syslog can drastically impact performance, especially if michael@0: syslog is configured for remote logging! Make sure you understand the michael@0: implications of outputting to syslog before you use these macros. In michael@0: general, it's wise to use these macros sparingly. michael@0: michael@0:

Strip Logging Messages

michael@0: michael@0:

Strings used in log messages can increase the size of your binary michael@0: and present a privacy concern. You can therefore instruct glog to michael@0: remove all strings which fall below a certain severity level by using michael@0: the GOOGLE_STRIP_LOG macro: michael@0: michael@0:

If your application has code like this: michael@0: michael@0:

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

The compiler will remove the log messages whose severities are less michael@0: than the specified integer value. Since michael@0: VLOG logs at the severity level INFO michael@0: (numeric value 0), michael@0: setting GOOGLE_STRIP_LOG to 1 or greater removes michael@0: all log messages associated with VLOGs as well as michael@0: INFO log statements. michael@0: michael@0:

Notes for Windows users

michael@0: michael@0:

Google glog defines a severity level ERROR, which is michael@0: also defined in windows.h michael@0: There are two known workarounds to avoid this conflict: michael@0: michael@0:

michael@0: michael@0:

See michael@0: this issue for more detail. michael@0: michael@0:


michael@0:
michael@0: Shinichiro Hamaji
michael@0: Gregor Hohpe
michael@0: michael@0:
michael@0: michael@0: michael@0: