One of the most appealing features of a software receiver is the ability to observe absolutely every single detail of its internals. The user might want to extract statistics, observe the behavior of a certain method, state machine or variable, or help debugging some piece of code. Moreover, it is desirable to do it in a quietly and ordered manner, without bloating the terminal with information that could bother other users and without affecting so much the performance of the receiver, specially when working in real-time with a Release build of the executable (see the Building Guide for more details about that).
In order to keep an annotated log of everything that is happening during the execution of the software receiver, GNSS-SDR implements application-level logging via google-glog, a library widely used at Google that provides logging APIs based on C++-style streams and various helper 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.
For instance, you can log a message by simply streaming things LOG(<a particular severity level>), e.g.
#include <glog/logging.h>
int main(int argc, char* argv[])
{
// Initialize Google's logging library.
google::InitGoogleLogging(argv[0]);
// ...
LOG(INFO) << "Total run time: " << rt_seconds << " [s]";
}You can specify one of the following severity levels (in increasing order of severity): INFO, WARNING, ERROR, and FATAL. 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.
Unless otherwise specified, in Linux machines glog writes to the filename "/tmp/<program name>.<hostname>.<user name>.log.<severitylevel>.<date>.<time>.<pid>" (e.g., /tmp/gnss-sdr.MyMachine.carles.log.INFO.20120709-222411.10474). You can override the default logging path with the following command line flag when invoking gnss-sdr:
$ ./gnss-sdr --log_dir=path/to/log
By default, glog copies the log messages of severity level ERROR or FATAL to standard error (stderr) in addition to log files. Sometimes, you may only want to log a message under certain conditions. You can use the following macros to perform conditional logging:
LOG_IF(INFO, num_observables > 10) << "Got 10 observables";The "Got 10 observables" message is logged only when the variable num_observables exceeds 10. 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.
LOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th observable";The above line outputs a log messages on the 1st, 11th, 21st, ... times it is executed. Note that the special google::COUNTER value is used to identify which repetition is happening.
You can combine conditional and occasional logging with the following macro:
LOG_IF_EVERY_N(INFO, (phase_is_available==1), 10) << "Got the "
<< google::COUNTER << "th phase observable";Instead of outputting a message every nth time, you can also limit the output to the first n occurrences:
LOG_FIRST_N(INFO, 20) << "Got the " << google::COUNTER << "th observable";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:
DLOG(INFO) << "PVT fix";
DLOG_IF(INFO, num_observables > 10) << "Got 10 observables";
DLOG_EVERY_N(INFO, 10) << "Got the " << google::COUNTER << "th observable";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:
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";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.
This is just a summary of what google-glog can do. We strongly suggest to check the official google-glog documentation for more features that can be useful for your logging purposes.
See also:
How to observe the internals of the software receiver.
