Integrate logging into your C++ Project. Do it right — do it once!
Iryna Mykytyn
Helping businesses to build AI/ML solutions and LLM integrations | Team Builder | Engineering Leader | Founder and CEO of COXIT
Almost half of the C++ Linux projects I’ve been working with - always had some kind of logging implemented, but it never had any set of rules or practices discussed before starting the project regarding when logs should be added, what should be message format, how many log levels is needed for this exact project, where logs should be stored, how it will be rotated/accessed, etc.
As a result, nobody paid attention to adding meaningful/accurate logs, and nobody could rely on getting useful insights on “why your server crashed last night” from logs.
Why logging is important?
Because sooner or later you will run your C++ server on some remote machine, and you will need to monitor how it runs, or investigate when it crashes ASAP. With good structured and easy readable logs you should be able to do it really ASAP.
Basically, there always were two kinds of projects: some which are just starting, and some which were started a few years ago, and by now have a pretty solid number of code lines. If you are dealing with the second one you are in the worst position — integrating logging into an existing big codebase may be painful, and even, if you have it integrated already, but nobody guarded it this gonna be a long and boring story changing it now.
In this article let’s consider the first case. You and your team are just starting a new C++ project from scratch. This is just the right time to integrate logging and agree on logging rules before it’s too late and not a priority.
Let’s do it by asking the right questions!
4 questions to be answered before start adding logs:
1.What logging library is the best fit for my C++ Linux project?
There are few options for C++ logging libraries. Which one to use depends on how big and complex your project gonna become. But besides that, the minimal set of features it should have is:
- multithreading/async writing to log files;
- configuration from the config file and trace filtering from config;
- log rotation support;
- good documentation and library support itself.
2.Which library to pick?
- There are around 10 possible options for C++: Pantheios, Glog, log4cpp, P7, G3log, Spdlog, Easylogging, Boost.Log.
- So, what library to pick? If your project is kind of small, hobby projects pick Glog or Log4cpp.
- Otherwise, you should be looking for a well-optimized and customizable solution which could be P7 or boost::log.
- Interesting fact: among all libs, only Glog has crash handling support (SIGSEGV, SIGILL, SIGFPE, SIGABRT, SIGBUS, SIGTERM). Which is really good for C++ applications.
3.How are you gonna read your logs?
This may affect log format and where you keep your logs. Here is an article where you can read about 4 different tools which let you read logs in Unix/Linux systems: Best Linux Log Monitoring and Management Tools.
If you picked the P7 library, it will be useful to take a look at their own tools: Baical.
4.What should be logged message format?
Kind of standard format is: [Time][Log level] — [File]:[Line] [Function] — [Text]. If the app is multithreaded/modular, add [Module][Thread] options as well. Set names to threads, don’t be lazy, it will be much more readable.
Above you can see an example of how logs could be visualized if you set up it right.
In my next post, I will show you an example of how we in COXIT dealt with integrating a logging system into one pre-release project.
Sum up
Logging is not easy. It requires a special way of thinking and balancing. At some point, you will naturally run into the question: what severity level should this log be, and how many logs should we add to not make code messy?
There is no exact instruction on this. You should make up your own pattern. Here are readings I recommend on this topic: Logging Level, Logging Best Practices.
In short, the way you should be thinking about it is: “what info will be potentially helpful if something goes wrong in this exact function?”. Really think about it. Also, “will somebody who didn't develop the code understand log message?”. In other words: “Is there enough context?”.
When you fix some new bug or review someone else bug fix, also, think in this way: “what log info would be helpful to find this bug sooner?”, and don’t be lazy to add it!
System Development Engineer at Amazon | AWS Developer Associate Certified | Cloud Application development | Native C++ Development | Building Scalable Solutions on AWS
2 年Nice article! "Logging Level,?Logging Best Practices" Links are pointing to 502.