a comfortable lightweight C++ logging library -- header-only, cross-platform, C++11.
Building this library first came to my mind when I was working with Boost.Log and experienced some problems with it.
Don't get me wrong Boost.Log is a great library, but one day when I started building a sandboxed app for Apple's OSX 10.8, Boost.Log gave me a headache.
I thought a bit about logging in general and decided to create a lightweight logging library. My goal was to build a library which is as comfortable as possible and which has as few logging overhead as possible.
-
The preprocessor
MLOG_NO_LIB
makes this library header-only. -
Here are the speed test results on my MacBook Air (1.86 GHz Intel Core 2 Duo, 4GB RAM):
### single-threaded standard logger test ### 0.005545ms for each log statment. 0.00789ms for each log statment with thread id. 0.01663ms for each log statment with thread id and timestamp.
### multi-threaded standard logger test ### 0.027485ms for each log statment. 0.03672ms for each log statment with thread id. 0.050505ms for each log statment with thread id and timestamp.
### single-threaded memory logger test ### 4e-05ms for each log statment. 4.5e-05ms for each log statment with thread id. 9e-05ms for each log statment with thread id and timestamp.
### multi-threaded memory logger test ### 0.00013ms for each log statment. 0.0001ms for each log statment with thread id. 0.0001ms for each log statment with thread id and timestamp.
### single-threaded file logger test ### 0.00037ms for each log statment. 0.001385ms for each log statment with thread id. 0.002795ms for each log statment with thread id and timestamp.
### multi-threaded file logger test ### 0.00457ms for each log statment. 0.01448ms for each log statment with thread id. 0.021335ms for each log statment with thread id and timestamp.
Basically you just have to include the mlog/mlog.hpp and use one of the logging macro functions.
#include <mlog/mlog.hpp>
//...
MLOG_INFO("this is your first log entry.")
There are 12 different macro functions.
The follow macro functions accept char*
, std::string
and boost::format
:
MLOG_TRACE()
MLOG_DEBUG()
MLOG_INFO()
MLOG_WARNING()
MLOG_ERROR()
MLOG_FATAL()
Example: MLOG_INFO("how to log");
and MLOG_INFO(boost::format("how to log with format: %1%.") % 23);
The next functions work with std::stringstream
:
MLOG_TRACE_STREAM()
MLOG_DEBUG_STREAM()
MLOG_INFO_STREAM()
MLOG_WARNING_STREAM()
MLOG_ERROR_STREAM()
MLOG_FATAL_STREAM()
Example: MLOG_INFO_STREAM("how to log " << "with a stream");
The trace and debug log statments only work if MLOGDEBUG and MLOGTRACE are defined as a preprocessor flag. If this is not the case the debug and trace statments will be ignored completely. These statements won't affect the performance of your program any more. I just recommand you to use Boost.Format is stead of the std::stringstream version. It's faster.
To build the library and with CMake, you will need to have CMake version 2.6 or higher installed appropriately in your system.
$ cmake --version
cmake version 2.8.1
Inside the mlog project directory, you can issue the following statements to configure and generate the Makefiles.
$ cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
Once CMake is done with generating the Makefiles and configuring the project, you can now build the library.
$ make
The mlog::mlogger
is a static std::unique_ptr<mlog::logger>
and contains the current log destination.
The standard destination is a mlog::standard_logger
. Reset the mlog::mlogger
to use another destination.
Example:
#include <mlog/mlog.hpp>
#include <mlog/file_logger.hpp>
//...
mlog::mlogger.reset(new mlog::file_logger("log.txt"));
MLOG_TRACE("Write this into log.txt");
This library is already shipped with the followed logger types:
Logger Name | Description |
---|---|
mlog::standard_logger | Is logging into std::cout |
mlog::standard_logger_thread_safe | Is logging thread safe into std::cout |
mlog::file_logger | Is logging into a file |
mlog::file_logger_thread_safe | Is logging thread safe into a file |
mlog::memory_logger_normal | Is logging thread safe into the memory (holds the last 4096 log entrys) |
mlog::memory_logger_big | Is logging thread safe into the memory (holds the last 65535 log entrys) |
It is possible to create your own logger class if you want to write your log at some place in the network or something like that. You just have to write a logger class and overload the mlog::logger::write_to_log()
function.
mlog::logger interface:
namespace mlog
{
class logger
{
public:
virtual void write_to_log(log_metadata&& metadata, std::string&& log_text) = 0;
};
}