A lightweight C++ logging library
Documentation can be found at https://emilk.github.io/loguru/index.html.
This software is in the public domain. Where that dedication is not recognized, you are granted a perpetual, irrevocable license to copy, modify and distribute it as you see fit.
Loguru is also available under The Unlicense.
That being said, I would appreciate credit! If you find Loguru useful, tweet me at @ernerfeldt mail me at [email protected].
I have yet to come across a nice, light-weight logging library for C++ that does everything I want. So I made one!
In particular, I want logging that produces logs that are both human-readable and easily grep:ed. I also want to be able to hook into the logging process to print some of the more severe messages on-screen in my app (for dev-purposes).
loguru.hpp and loguru.cpp.loguru.cpp or just #include <loguru.cpp> in one of your own .cpp files.#includes for fast compile times (see separate heading).CHECK_F(fp != nullptr, "Failed to open '%s'", filename)ABORT_F("Something went wrong, debug value is %d", value).some_function_name(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)some_function_name(std::vector<std::string> const&)#define LOGURU_USE_FMTLIB 1, before including loguru.hppfmtlib include directory for building as well as linking against fmtlib, alternatively use the FMT_HEADER_ONLY preprocessor definition.noreturn for the benefit of the static analyzer and optimizer.loguru::g_flush_interval_ms in a background threadloguru::set_thread_name).Just include <loguru.hpp> where you want to use Loguru.
Then either compile and link with loguru.cpp or in one .cpp file: #include <loguru.cpp>
Make sure you compile with -std=c++11 -lpthread -ldl on relevant environments.
Loguru can be added to an existing CMake project in three ways
add_subdirectory()FetchContent()find_package()See CMake example for a demonstration.
…If you prefer logging with streams:
#define LOGURU_WITH_STREAMS 1
#include <loguru.hpp>
...
LOG_S(INFO) << "Look at my custom object: " << a.cross(b);
CHECK_EQ_S(pi, 3.14) << "Maybe it is closer to " << M_PI;For more info, see the official documentation.
Alternatively, you can build and install loguru using vcpkg dependency manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install loguruThe loguru port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please create an issue or pull request on the vcpkg repository.
# Only show warnings, errors and fatal messages:
cat logfile.txt | egrep "[^0-9]\|"
# Ignore verbosity-levels 4 and above:
cat logfile.txt | egrep "[^4-9]\|"
# Only show verbosity-level 6:
cat logfile.txt | egrep "6\|"
# Only show messages from the main thread:
cat logfile.txt | egrep "\[main thread \]"I abhor logging libraries that #include's everything from iostream to windows.h into every compilation unit in your project. Logging should be frequent in your source code, and thus as lightweight as possible. Loguru's header has no #includes. This means it will not slow down the compilation of your project.
In a test of a medium-sized project, including loguru.hpp instead of glog/logging.hpp everywhere gave about 10% speedup in compilation times.
Note, however, that this gives you the bare-bones version of Loguru with printf-style logging. If you want std::ostream style logging (or GLOG functionality) you need to #define LOGURU_WITH_STREAMS 1 before #include <loguru.hpp>, and that will make loguru.hpp include <sstream>. No away around it!
The library supports scopes for indenting the log-file. Here's an example:
int main(int argc, char* argv[])
{
loguru::init(argc, argv);
LOG_SCOPE_FUNCTION(INFO);
LOG_F(INFO, "Doing some stuff...");
for (int i=0; i<2; ++i) {
VLOG_SCOPE_F(1, "Iteration %d", i);
auto result = some_expensive_operation();
LOG_IF_F(WARNING, result == BAD, "Bad result");
}
LOG_F(INFO, "Time to go!");
return 0;
}This will output:
…ERROR_CONTEXTYou can also optionally log things ONLY if there is a crash. This is a very useful feature:
void process_file(const char* filename)
{
ERROR_CONTEXT("filename", filename);
parse_file(filename); // Only if this crashes will filename be logged.
}Some logging libraries only supports stream style logging, not printf-style. This means that what in Loguru is:
LOG_F(INFO, "Some float: %+05.3f", number);in Glog becomes something along the lines of:
LOG(INFO) << "Some float: " << std::setfill('0') << std::setw(5) << std::setprecision(3) << number;Loguru allows you to use whatever style you prefer.
No open issues yet, or sync has not completed.