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"
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:
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.
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.
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.
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
.
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>
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.
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>
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.
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)
Writing configuration files that can be used by KDSPDSetup is simple.
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:
Please note that the suffix _st
refers to single thread, and _mt
to multiple threads.
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"
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 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.
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.
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.
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: