Loading repository data…
Loading repository data…
Timothy-Liuxf / repository
simple_logger - A simple, multifunctional and header-only logging library for C++17.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
simple_logger, a simple, multifunctional and header-only log library for C++17.
iostream style, function style and format styleMSVC, GCC and Clang, etc. supporting C++17 standard or above.
Run:
$ git clone https://github.com/Timothy-Liuxf/simple_logger.git --recursive
or
$ git clone https://github.com/Timothy-Liuxf/simple_logger.git
$ cd simple_logger
$ git submodule update --init --recursive
simple_logger is a header-only library and needn't to be built. Just add the include and third_party/fmt/include directories into the include directories of your C++ project and include simple_logger/simple_logger.hpp to get started.
There are six log levels in simple_logger: Trace, Debug, Info, Warn, Error and Fatal. The first two levels will print log messages into stdout, while the other two will print into stderr. By default, log messages in Debug level and Trace level are NOT printed.
There are three styles to log messages.
You can log messages in C++ iostream style:
#include <simple_logger/simple_logger.hpp>
using namespace simple_logger;
int main() {
logger.Trace() << "This message shouldn't be printed by default!";
logger.Debug() << "This message shouldn't be printed by default!";
logger.Info() << "Info message: <" << 8888 << '>';
logger.Warn() << "Warn message: <" << 8888 << '>';
logger.Error() << "Error message: <" << 8888 << '>';
logger.Fatal() << "Fatal message: <" << 8888 << '>';
return 0;
}
You can also log messages just as a variadic function:
#include <simple_logger/simple_logger.hpp>
using namespace simple_logger;
int main() {
logger.Trace("This message shouldn't be printed by default!");
logger.Debug("This message shouldn't be printed by default!");
logger.Info("Info message: <", 8888, '>');
logger.Warn("Warn message: <", 8888, '>');
logger.Error("Error message: <", 8888, '>');
logger.Fatal("Fatal message: <", 8888, '>');
return 0;
}
You can also log messages in C++20 format library style:
#include <simple_logger/simple_logger.hpp>
using namespace simple_logger;
int main() {
logger.Tracef("This message shouldn't be printed by default!");
logger.Debugf("This message shouldn't be printed by default!");
logger.Infof("Info message: <{}>", 8888);
logger.Warnf("Warn message: <{}>", 8888);
logger.Errorf("Error message: <{}>", 8888);
logger.Fatalf("Fatal message: <{}>", 8888);
return 0;
}
With fmtlib, simple_logger can support almost all formatting methods in fmtlib. Such as:
Format ranges:
#include <simple_logger/simple_logger.hpp>
#include <fmt/ranges.h>
#include <array>
using namespace simple_logger;
int main() {
std::array arr {0, 1, 2, 3};
logger.Infof("Info message: {}", arr);
return 0;
}
Format time:
#include <simple_logger/simple_logger.hpp>
#include <fmt/chrono.h>
#include <chrono>
using namespace simple_logger;
int main() {
auto current_time = fmt::localtime(
std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()));
logger.Infof("Info message: current_time: {:%Y-%m-%d %H:%M:%S}",
current_time);
return 0;
}
Literal-based format
#include <simple_logger/simple_logger.hpp>
#include <fmt/format.h>
using namespace simple_logger;
int main() {
using fmt::literals::operator""_a;
logger.Infof("Info message: {num}", "num"_a = 5);
return 0;
}
For more usage, please see fmtlib API documentation.
To specify log levels, you should define the following macros before including simple_logger/simple_logger.hpp:
SIMPLE_LOGGER_DISABLE_LOG: No logs will be printedSIMPLE_LOGGER_ENABLE_LOG_TRACE: Log messages on Trace, Debug, Info, Warning, Error and Fatal levels will be printedSIMPLE_LOGGER_ENABLE_LOG_DEBUG: Log messages on Debug, Info, Warning, Error and Fatal levels will be printedSIMPLE_LOGGER_ENABLE_LOG_INFO: Log messages on Info, Warning, Error and Fatal levels will be printedSIMPLE_LOGGER_ENABLE_LOG_WARN: Log messages on Warning, Error and Fatal levels will be printedSIMPLE_LOGGER_ENABLE_LOG_ERROR: Log messages on Error and Fatal levels will be printedSIMPLE_LOGGER_ENABLE_LOG_FATAL: Only log messages on Fatal level will be printedSIMPLE_LOGGER_ENABLE_LOG_INFO is definedThe log object logger is thread-safe. To use thread-unsafe log to avoid improve performance, you can use uslogger. For an example, the following code will cause chaos (changing uslogger to logger would fix it):
#include <simple_logger/simple_logger.hpp>
#include <memory>
#include <thread>
#include <utility>
#include <vector>
constexpr std::size_t nthreads = 128;
using namespace simple_logger;
int main(int argc, char*[]) {
std::vector<std::unique_ptr<std::thread>> threads(nthreads);
for (std::size_t i = 0; i < nthreads; ++i) {
threads[i] = std::make_unique<std::thread>([i, argc] {
std::this_thread::yield();
uslogger.Info() << "Thread-unsafe "
<< "log. "
<< "[argc: " << argc << "] "
<< "At "
<< "Index: " << i << ".";
});
}
for (std::size_t i = 0; i < nthreads; ++i) {
threads[i]->join();
threads[i].reset();
}
return 0;
}
Source code of the examples are in the examples directory.
To build the examples:
For all platforms with CMake, run:
$ mkdir build
$ cd build
$ cmake ..
$ make -j$(nproc)
For Unix-like platforms with GNU Autotools, run:
$ autoreconf -i
$ BUILD_TEST_EXAMPLES=1 ./configure
$ make -j$(nproc)
To run the examples, then run:
$ ./examples/<example_name>
The <example_name> is the same as the name of the corresponding source file after removing the extension name .cc.
Copyright (C) 2023, Timothy Liu
All rights reserved