Oak is a lightweight logging library written in C++23, designed to simplify logging in modern C++ applications.
This code was originally forked from the logger of Brenta Engine in order to develop it independently from the engine.
-
Thread-Safety: Oak ensures safe logging in multi-threaded environments, preventing data races and synchronization issues.
-
Minimal Overhead: Optimized for performance, Oak introduces minimal runtime overhead, ensuring it doesn't compromise the speed of your application.
-
Simplicity and Ease of Use: Oak's API is intuitive, allowing you to integrate it seamlessly into your project without a steep learning curve.
-
Customization: Oak offers a range of customization options, allowing you to tailor the logging experience to your specific requirements.
-
multiple logging levels
-
log to file
-
log to unix sockets
-
log to net sockets
-
log metadata
-
settings file
-
json serialization
-
log buffering
-
async logging
If you don't want to mess with your build system, you can simply copy include/oak/oak.hpp and src/oak.cpp in your imports and sources respectively. Alternatively, you can add this repository as a git submodule and register it in cmake as a subdirectory, or fetch it using CPM:
CPMAddPackage(
NAME oak
GITHUB_REPOSITORY San7o/oak
GIT_TAG origin/main)
To learn about all the functionalities, please visit the html documentation. Here is presented a quick guide to showcase the library's api.
The logger uses a writer to read the message queue and correctly writes the output in the specified location, allowing buffering.
#include <oak/oak.cpp>
// ...
oak::init_writer();
// Do stuff and have fun here
oak::stop_writer();Log something with the level info:
oak::info("i love {}!", what);# output
[level=info] i love oak!Or use macros if you prefer:
OAK_INFO("add a {} to this library!", star);Only logs with an higher level will be logged:
oak::set_level(oak::level::debug);oak::set_flags(oak::flags::level, oak::flags::date);# example output
[level=info,date=2024-09-11] niceYou can also serialize the log adding the flag oak::flags::json:
{ "level": "output", "date": "2024-09-11", "time": "15:35:20", "pid": 30744, "tid": 9992229128130766714, "message": "Hello Mario" }
auto file = oak::set_file("/tmp/my-log");
if (!file.has_value())
oak::error("Error setting file: {}", file.error());The library uses std::expected to handle errors.
// unix sockets
oak::set_socket("/tmp/a-socket");
// net socket, defaults to tcp
oak::set_socket("127.0.0.1", 1337);
// udp net socket
oak::set_socket("127.0.0.1", 5678, protocol_t::udp);You can save the settings in a file with key=value,..., like this:
level = debug
flags = level, date, time, pid, tid
file = tests/log_test.txt
And use this settings like so:
auto r = oak::settings_file("settings.oak");
if (!r.has_value())
oak::error("Error opening setting file: {}", r.error());oak::async(oak::level:debug, "Time travelling");Any new contributor is welcome to this project. Please read CONTRIBUTING for intructions on how to contribute.
The test project uses cmake. To build and run the tests, run:
cmake -Bbuild
cmake --build build -j 4
./build/testsThe project's documentation uses doxygen, to generate the html documentation locally, please run:
make docsThe library uses clang-format for formatting, the rules are saved in
.clang-format.
To format the code, run:
make formatThe library is licensed under MIT license.
