Debug · Google Logging Library 101

Jun 9, 2024 | Tech Software

Preface

The Google Logging Library, glog, is super handy and worth taking some notes for quick reference. This post mostly refers to article How To Use Google Logging Library, with minor modification, simplification, and styling. Credits go to the origin post authors.

Introduction

glog is a library that implements application-level logging. This library provides logging APIs based on C++ stream styles with various helper macros. You can log a message by simply streaming things to LOG(SEVERITY_LEVEL), e.g.

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

Severity Level

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

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

Unless otherwise specified, glog writes to /tmp/<program_name>.<host_name>.<user_name>.log.<severity_level>.<date>.<time>.<pid> files, with one separate file for each severity level, and copies ERROR and FATAL log messages to stderr in addition to the files.

Setting Flags

Several flags influence glog's output behavior. If gflags, Google Commandline Flags, is installed on your machine, its configure script will automatically detect and use it. It allows you to pass flags on the command line. Otherwise, you can set flags via environment variables.

For more information on flags and their adjustments, see Adjusting Output. For even more details see glog's source code on flags.

Conditional and Occasional Logging

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

If a line of code is executed many times, it may be useful to only log a message at certain intervals. This kind of logging is most useful for informational messages.

Note that google::COUNTER value is used to identify which repetition is happening. You can combine conditional and occasional logging with the following macro.

Instead of outputting a message every nth time, you can also limit the output to the first N occurrences:

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

Debug Mode Support

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

CHECK Macros

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

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

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

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

You can use CHECK_NOTNULL to check if a pointer is nullptr. Since this macro returns the given pointer, this is very useful in constructor initializer lists.

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

If you are comparing C strings (char *), a handy set of macros performs case sensitive as well as case insensitive comparisons - CHECK_STREQ, CHECK_STRNE, CHECK_STRCASEEQ, and CHECK_STRCASENE. The CASE versions are case-insensitive. You can safely pass NULL pointers for this macro. They treat NULL and any non-NULL string as not equal. Two NULLs are equal. Note that both arguments may be temporary strings which are destructed at the end of the current "full expression", for example, CHECK_STREQ(Foo().c_str(), Bar().c_str()) where Foo and Bar return C++'s std::string.

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

Verbose Logging

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

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

Failure Signal Handler

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

By default, the signal handler writes the failure dump to stderr. You can customize the destination by InstallFailureWriter().