Wednesday, December 28, 2016

Choose a C++ Logging Library


I'm recently searching for a logging library to use in a C++ project.  I have some requirements (some are hard, some are optional).  I surveyed a lot of choices and reached a conclusion that none of existing libraries can meet all of my requirements. Overall spdlog is decent enough, with some gaps that I can bridge with a wrapper layer.  The final solution is my wrapper layer on top of spdlog.



My requirements:

  1. (MUST) This library will be used in another manager project (which uses glog).  Usually each machine runs one manager, but the manager can start 1000s of instance of this library. We want different instances to log into different files. So it's mandatory that we configure logging inside the library which is different than the manger logging config.
  2. (MUST) Log entry should show "timestamp : source file name : method name : line no."
  3. (MUST) Able to log to both file and stdout/stderr, to ease debugging work.
  4. (good to have) able to auto-rotate, limited by log file size and number of files. For example, I want the log files to be in "/var/log/myprj/",  no more than 5 log files accumulated, each file less than 10 MB.
  5. (good to have) log format similar to google log: 
  6.           LOG(INFO) << "this is line 1" << value << ", continue...";
  7. (good to have)  can put logging configs in a config file, similar to log4j.
  8. (good to have)  can change the logging level at runtime, i.e., you can control what log severity to output at runtime without restarting the program.

Survey

I read a lot of posts and below is my personal summary.

google log (glog)

We have been using this for our previous C++ projects.   So far so good.
Pros
Mature and stable. Readily available as pre-built packages.
Lots of helper macros. No configuration needed, no dependency, install-and-play
Tons of flexible cmd-line options when combined with gflag library

Cons
the lack of log rotation:  no support for specifying number of log files.
Conflicts with upper layer manager's log config, cannot specify per library instance's own logging file.
Always append "yyyymmdd_hhmmss.pid" string to end of log file. This effectively creates a new log file with totally different file name every time program restarts.  This make it hard for log-rotator to rotate the log files based on name.

--max_log_size=size (MB) to specify log file size,  --log_dir=dir to specify log file dir.  "--logtostderr=1" to output log to stderr (in addition to files).

Boost.log V2

Haven't tried it.  By reading posts, this is a very comprehensive framework for logging in C++.  It is very heavy, slow in speed, big generate code size. Not seem like a good fit for our project.

log4cxx

An Apache incubator project,  not actively maintained.  It tries to simulate log4j, relies on log4j package.

log4cpp

Pros
Mature, has pre-built ubuntu package.  .
Try to follow log4j patterns. Use similar log4j properties file to configure every aspect of logging

Cons
complicated syntax to init logger/appender/sinker
doesn't support line number of source file name in log entry (a deal breaker)

spdlog

Pros:
(1) Judging from github page, it seems like a fast and simple library (The fastest logging library). (2) Header files only so you can copy the dir into your project and compile directly.
(3) Mature. Has pre-built ubuntu package
(4) Good document for a quick start
(5) Particularly, log rotate works great to limit log file size and number of files.
(6) 1600+ stars on github. Actively maintained.

Cons:
 (1) It doesn't support the glog logging style.  But it supports a python-style format which I actually prefer, so I can live with it.
 (2) It doesn't seem to allow including "source file name : function name : line number" into log entry.  (this can be hacked using macros defines)

easyloggingcpp

Another header-only library.
Pros:
(1) one header file only, very simple to include into project.
(2) Support the convenient glog style
(3) Allow to include filename, function name, line number in log entry.
(4) 1000+ stars on github, very actively maintained

Cons:
It doesn't support limiting the number of log files.  Log file size limiting is very unreliable.

Conclusion

Given all the pros and cons, there is no solution that's readily available to meet all of our requirements.  "spdlog" is the closest one among these candidates.  We will build a wrapper layer on top of spdlog to fill up the small gap to reach our goals.  The final code is here.

1 comment: