Skip to content

A small library in modern C to initialize spdlog loggers from a toml configuration file.

Notifications You must be signed in to change notification settings

KDAB/KDSPDSetup

Repository files navigation

KDSPDSetup

MIT LicenseC  CMakeGitLinuxWindowsmacOS

Overview

KDSPDSetup is a minimal reimplementation of the unmaintained spdlog_setup library for modern C projects.

Complete documentation is available here.

Given a TOML file containing configuration parameters, spdlog loggers for your project can be set up with a single call to KDSPDSetup::setupFrom, as shown below:

#include <KDSpdSetup/kdspdsetup.h>

int main()
{
    KDSPDSetup::setupFrom("example.toml");

    auto logger = spdlog::get("root");
    logger->debug("Hello spdlog!");
}

// [2023-10-30 14:35:19.244] [root] [debug] Hello spdlog!

The configuration file for this example, example.toml, might look like this:

[[sink]]
name = "console_st"
type = "stdout_sink_st"

[[logger]]
name = "root"
sinks = ["console_st"]
level = "debug"

Requirements

You will need a compiler that supports the C 20 standard.

Our CI has successfully built and tested on these environments:

Platform Kernel Arch Compiler Compiler Version
Windows 10 Microsoft Windows [Version 10.0.19044.1526] x64 MSVC 19.34.31937.0
Ubuntu GNU/Linux 4.15.0-167-generic #175-Ubuntu SMP x64 GCC 11.4.0
MacOS Darwin Kernel Version 22.6.0 xnu-8796.141.3.701.17 arm64 clang 14.0.3.14030022

The following compiler versions should be sufficient, but this has not been fully tested:

GNU Badge LLVM Badge Visual Studio Badge NVIDIA Badge Intel Badge
GCC 10 Clang 8 MSVC 19.22 NVCC 12.0 Intel C 2021.1

If any dependencies are not found, CMake's FetchContent will use git to retrieve them. Thus, git is also a requirement in this case.

Dependencies

Aside from spdlog, there are three additional dependencies:

Purpose Lib Needed
TOML parsing toml11 Always
Testing doctest Tests only
Documentation doxygen Documentation only

These dependencies will be automatically downloaded with git if not found.

Build & Install

Build

You'll need at least CMake 3.11 to build this library.

You can skip to the CMake Presets section if you'd like to use a preset that will set the source and build directories for you, along with some flags.

To configure and build, use the following cmake commands:

$ cmake -S <source-dir> -B <build-dir> <flags>
$ cmake --build <build-dir>

where <source-dir> is the root directory of this project and <build-dir> is the desired build directory.

<flags> can be empty or contain one or more of the flags detailed in the Tests, Examples, and Documentation sections below.

For example, from this directory one might run the following:

$ cmake -S . -B build
$ cmake --build build

which creates the directory build if it does not exist, configures CMake, and builds the project.

CMake Presets

There are a number of CMake presets included. These will configure a build with specific flags set for either development or release.

dev-* configurations will add tests and documentation to the build targets. They also build in CMake's Debug mode, which will enable debug symbols and will NOT use compiler optimization flags.

release-* configurations will not build tests or documentation. They build in CMake's Release mode, which will use compiler optimization and will NOT build with debug symbols.

Examples will be built with both types of preset unless explicitly disabled with -DKDSPDSETUP_BUILD_EXAMPLES=OFF.

Here are all the presets:

  • dev-gcc
  • dev-clang
  • dev-msvc
  • release-gcc
  • release-clang
  • release-msvc

To build from this directory with a preset (we'll use dev-gcc as an example), one would run the following:

$ cmake --preset dev-gcc
$ cmake --build build-dev-gcc

Note that for preset name presetName the build directory will be titled build-presetName.

Install

To install the library on your system, after completing the steps in the Build section above, run the following command:

$ sudo cmake --install <build-dir>

Tests

You can build the unit tests by passing the flag -DKDSPDSETUP_BUILD_TESTS=ON to CMake:

$ cmake -S <source-dir> -B <build-dir> -DKDSPDSETUP_BUILD_TESTS
$ cmake --build <build-dir>

The dependency doctest will only be used when this flag is on.

Examples

Building examples is on by default.

To disable the basic examples, pass the flag -DKDSPDSETUP_BUILD_EXAMPLES=OFF to CMake:

$ cmake -S <source-dir> -B <build-dir> -DKDSPDSETUP_BUILD_EXAMPLES=OFF
$ cmake --build <build-dir>

Documentation

The documentation for this project is available online.

To build the documentation locally, pass the flag -DKDSPDSETUP_BUILD_DOCS=ON to CMake.

$ cmake -S <source-dir> -B <build-dir> -DKDSPDSETUP_BUILD_DOCS
$ cmake --build <build-dir>

The dependency doxygen will only be used when this flag is on.

Usage

Use With CMake Project

To use the library in a CMake project, make sure to install the library.

Then, simply write the following line in your CMakeLists.txt:

find_package(KDSpdSetup)

and after adding your target, let's call it untitled, link with this CMake command:

target_link_libraries(untitled KDSpdSetup::KDSpdSetup)

Configuration

Writing configuration files that can be used by KDSPDSetup is simple.

Sinks

To configure a sink, a name and sink type must be provided:

[[sink]]
name = "some_name"
type = "stdout_sink_st"

Optionally, a level can also be specified:

[[sink]]
name = "stdout_error"
type = "stdout_sink_mt"
level = "err"

Some sink types require additional fields, or allow additional optional fields.

The list below details the sink types which have additional required fields:

type required field value type
basic_file_sink_st
basic_file_sink_mt
filename string
rotating_file_sink_st
rotating_file_sink_mt
base_filename
max_size
max_files
string
string
int
daily_file_sink_st
daily_file_sink_mt
base_filename
rotation_hour
rotation_minute
string
int
int

All of the above sink types can also optionally specify the boolean truncate, which defaults to false if not specified.

The syslog sink types, syslog_sink_st and syslog_sink_mt, have four optional fields that generally do not need to be filled (but can be if needed):

key name value type default value
ident string ""
syslog_option int 0
syslog_facility int 1

Note that a syslog_facility value of 1 is the plain integer value for LOG_USER.

Here is a full list of currently supported sink types and the platforms on which they are available:

Sink Type Platform(s)
stdout_sink_st All
stdout_sink_mt All
color_stdout_sink_st All
color_stdout_sink_mt All
basic_file_sink_st All
basic_file_sink_mt All
rotating_file_sink_st All
rotating_file_sink_mt All
daily_file_sink_st All
daily_file_sink_mt All
null_sink_st All
null_sink_mt All
syslog_sink_st Linux
syslog_sink_mt Linux
msvc_sink_st Windows
msvc_sink_mt Windows

Please note that the suffix _st refers to single thread, and _mt to multiple threads.

Patterns

The global pattern is defined as a free-standing key-value pair (not under a [[pattern]] or any other table):

global_pattern = "[%Y-%m-%dT%T%z] [%L] <%n>: %v"

If global_pattern is not specified, the spdlog uses the default pattern “[%Y-%m-%d %H:%M:%S. %e] [%l] [%n] %v”.

Additionally, named patterns can be defined and reused with several different loggers:

[[pattern]]
name = "short_pattern"
value = "%c-%L: %v"

Thread Pools

An async logger takes a thread pool as an argument to its constructor. This can be either a global thread pool, or a manually constructed one.

The global thread pool is defined as a table with single brackets ([global_thread_pool], not [[global_thread_pool]]) because it is one table, not an array of tables. Named thread pools are members of the array of tables [[threadpool]].

Both require integers queue_size and num_threads, while non-global thread pools also require a name.

[global_thread_pool]
queue_size = 8192
num_threads = 1

[[thread_pool]]
name = "tp"
queue_size = 4096
num_threads = 2

Loggers

Loggers require a name, and a list of sink names:

[[logger]]
name = "my_logger"
sinks = ["console_sink_st", "console_sink_mt", "file_out", "file_err"]

Please keep in mind that each sink name must be a name from a [[sink]] defined somewhere in the configuration file. If the name is not found, std::out_of_range will be thrown.

Loggers can also optionally specify patterns and levels:

[[logger]]
name = "root"
sinks = [
    "console_st", "console_mt",
    "color_console_st", "color_console_mt",
    "daily_out", "daily_err",
    "file_out", "file_err",
    "rotate_out", "rotate_err",
    "null_sink_st", "null_sink_mt",
    "syslog_st", "syslog_mt"]
level = "trace"
pattern = "short_pattern"

The pattern name also must be defined somewhere in the configuration.

Asynchronous loggers can be defined by specifying type = "async":

[[logger]]
type = "async"
name = "my_async"
sinks = ["console_mt"]

Optionally, async loggers can have a specified thread pool and overflow policy:

[[logger]]
type = "async"
name = "local_async"
sinks = ["console_mt"]
pattern = "succient"
thread_pool = "tp"
overflow_policy = "overrun_oldest"

If no thread pool is specified, the global thread pool is used.

The options for overflow policy are "block" and "overrun_oldest". If not specified, "block" is used by default.

Example Files

This repository contains a few example configuration files:

  • examples/example.toml
  • tests/full/full-linux.toml
  • tests/full/full-linux.toml
  • tests/pre/pre.toml

Huge thanks to guangie88 for providing these examples in the original spdlog_setup project. The files in that project are available under the terms of the MIT license.

Licensing

KDSPDSetup is (C) 2023, Klarälvdalens Datakonsult AB, and is available under the terms of the MIT license.

Contact KDAB at [email protected] if you need different licensing options.

About KDAB

KDSPDSetup is supported and maintained by Klarälvdalens Datakonsult AB (KDAB).

The KDAB Group is the global No.1 software consultancy for Qt, C and OpenGL applications across desktop, embedded and mobile platforms.

The KDAB Group provides consulting and mentoring for developing Qt applications from scratch and in porting from all popular and legacy frameworks to Qt. We continue to help develop parts of Qt and are one of the major contributors to the Qt Project. We can give advanced or standard trainings anywhere around the globe on Qt as well as C , OpenGL, 3D and more.

Please visit https://www.kdab.com to meet the people who write code like this.

Stay up-to-date with KDAB product announcements: