Using Boost.Log – Part 1

This is an effort to illustrate the usage of Boost.Log with simple logging, filtering and the usage of a configuration file to manage logging level.

Basic logging

The first thing we need is to setup our project. I will use CMake as the build system.

To add Boost.Log library, is necessary to use the FindBoost module. Since version 3.30, it’s recommended to use the configuration file provided by Boost, avoiding a warning due to the policy CMP0167, therefore the usage of CONFIG in find_package.

cmake_minimum_required(VERSION 3.28)
project(MyLogger)

set(CMAKE_CXX_STANDARD 20)

find_package(Boost 1.83.0 REQUIRED COMPONENTS log log_setup CONFIG)

add_executable(custom_logger)
target_sources(custom_logger PRIVATE main.cpp)
target_link_libraries(custom_logger PRIVATE ${Boost_LIBRARIES})

custom_logger is the target (binary/executable).

Let’s take the Tutorial logging as reference.

Add a main.cpp to have a minimal running project. BOOST_LOG_TRIVIAL is intended to be a basic way to add console logs.

#include <boost/log/trivial.hpp>

int main() {
  BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
  BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
  BOOST_LOG_TRIVIAL(info) << "An informational severity message";
  BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
  BOOST_LOG_TRIVIAL(error) << "An error severity message";
  BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";

  return 0;
}
Basic logging with all severity levels
Basic logging

Adding filters

In order to show logs based on its severity, we use filters. At this time, I show the logs with info severity or higher.

#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/trivial.hpp>

namespace logging = boost::log;
namespace trivial = logging::trivial;

void init() {
  auto filter = trivial::severity >= trivial::info;
  logging::core::get()->set_filter(filter);
}

int main() {
  init();

  BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
  BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
  BOOST_LOG_TRIVIAL(info) << "An informational severity message";
  BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
  BOOST_LOG_TRIVIAL(error) << "An error severity message";
  BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";

  return 0;
}
Basing logging removing trace and debug logs
Basic logging with filtering

External configuration

Sometimes is preferable to change the filtering level by updating parameters external to the binary, like a configuration file. For this purpose, use the Boost.PropertyTree. It’s possible to use a variety of formats, I particularly stick with INI file.

Afterwards, create an app.ini in your project root.

[logs]
level = debug

The executable will look up that file in the same path, as a result is necessary to copy it there every time it changes when compiling, thus I use a CMake target.

set(PROPERTIES_FILE ${CMAKE_SOURCE_DIR}/app.ini)
add_custom_target(copy_properties ALL
        COMMAND ${CMAKE_COMMAND} -E copy_if_different
        ${PROPERTIES_FILE}
        $<TARGET_FILE_DIR:custom_logger>
        DEPENDS ${PROPERTIES_FILE}
)
add_dependencies(custom_logger copy_properties)

The read_ini loads the app.ini. To access a value, we use get on the property tree.

We want to allow trace or debug levels, with info as fallback.

#include <boost/property_tree/ini_parser.hpp>

namespace logging = boost::log;
namespace trivial = logging::trivial;

trivial::severity_level getFilteringLevel() {
  namespace property_tree = boost::property_tree;

  property_tree::ptree pt;
  read_ini("app.ini", pt);

  const auto level = pt.get<std::string>("logs.level");
  if (level == "trace")
    return trivial::trace;
  if (level == "debug")
    return trivial::debug;
  return trivial::info;
}

void init() {
  auto filter = trivial::severity >= getFilteringLevel();
  logging::core::get()->set_filter(filter);
}
Filtering level from INI file where the minimum level is debug
Filtering level from INI file

In future posts I will elaborate formatting to have custom logs messages and sinks such as console and files to have different “channels” to send your logs.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *