SLogLib是一个易于使用、完全可定制和可扩展的跨平台日志库。它支持用户定义的消息格式化、多种日志设备(包括控制台、文件和小部件)以及调用堆栈。以下是使用SLogLib所需的最基本代码:
C++代码示例:
#include "SLogLib/SLogLib"
void main() {
// 在程序开始处添加这些行。
// SLogLib会自动删除这些设备和格式化器。
using namespace SLogLib;
addLoggingDevice(new ConsoleLogger(new NullFormatter));
addLoggingDevice(new FileLogger("foo.log", new DetailedFormatter));
// 下一行将消息写入控制台和文件。
int a = 10;
double b = 15.3;
const char *c = "Success";
SLOGLIB_LOG_MSG_INFO("a = " << a << " b = " << b);
SLOGLIB_LOG_MSG_INFO(c);
}
第一行将控制台日志设备添加到SLogLib。日志设备使用格式化器在将消息写入底层设备之前对消息进行格式化。这里使用了NullFormatter,它什么也不做。控制台上的输出如下所示:
> a = 10 B = 15.3Success
请注意,两条消息都写在同一行。这是因为NullFormatter在每条消息后不添加新行。可以自己为每条消息添加新行,或者将AppendNewLine参数传递给NullFormatter的构造函数,以在每条消息后自动添加新行。
SLogLib可以将消息写入多个日志设备。第二行添加了一个文件日志设备,并使用详细的格式化器来写入消息。以下是写入文件的第一条消息:
Msg Level : 1 Time : 2015-2-12 17:57:11:151 Process ID : 4188 Thread ID : 7760 FileName : LoggingDemo.cpp FuncName : wmain Line No. : 15 CallStack : LoggingDemo.cpp : wmain [15] Message : a = 10 b = 15.3
一些重要点:
宏:
#define SLOGLIB_DISABLE_LOGGING
Disables all logging code at the compile time. This can be used to disable logging completely from the production builds. If is best to define this using the compiler arguments. If you wish to disable logging at the runtime use disableLogging() and enableLogging().
#define SLOGLIB_LOG_MESSAGE(level, msg)
Write a message at a specified level to all enabled logging devices.
#define SLOGLIB_LOG_MSG_INFO(m) SLOGLIB_LOG_MESSAGE(MESSAGE_LEVEL_INFO , m)
#define SLOGLIB_LOG_MSG_WARN(m) SLOGLIB_LOG_MESSAGE(MESSAGE_LEVEL_WARNING, m)
#define SLOGLIB_LOG_MSG_ERROR(m) SLOGLIB_LOG_MESSAGE(MESSAGE_LEVEL_ERROR , m)
#define SLOGLIB_LOG_MSG_DEBUG(m) SLOGLIB_LOG_MESSAGE(MESSAGE_LEVEL_DEBUG , m)
#define SLOGLIB_LOG_MSG_DETAIL(m) SLOGLIB_LOG_MESSAGE(MESSAGE_LEVEL_DEBUG , m)
The above convenience macros write the message at a predefined level.
#define SLOGLIB_ADD_TO_CALLSTACK
Add the function from which this macro is called to the current call stack. It can be used to build a call stack for only the important functions at the time of debugging. The call stack is included in
Message
and and can be written to logging devices.
函数:
void SLogLib::addLoggingDevice(AbstractLoggingDevice* device);
Add a specified logging device to the list of logging devices.
void SLogLib::removeLoggingDevice(AbstractLoggingDevice* device);
void SLogLib::removeLoggingDevice(const std::string& name);
Remove a logging device from the list of logging devices.
AbstractLoggingDevice* SLogLib::queryLoggingDevice(const std::string& name);
Get a pointer to the logging device. Note that the returned pointer must not be deleted or changed. If you wish to delete an existing logging device use removeLoggingDevice().
void SLogLib::writeMessage(const std::string& fileName, const std::string& funcName, unsigned int lineNo, unsigned int level, const std::string& msg);
Write a message to all active logging devices. The first three parameters must the file name, function name, and line number from which the message was logged from. The last two parameters are the level and the message to be written. You don't need to call this function directly;
SLOGLIB_LOG_MESSAGE
calls this function internally after automatically adding the file name, function name, and line number.
void SLogLib::disableLogging();
void SLogLib::enableLogging();
bool SLogLib::isLoggingEnabled();
Disable and enable logging at runtime. While logging is disabled all messages are ignored and they will not be written to logging devices once logging is enabled again.
也应该阅读AbstractLoggingDevice.h和AbstractFormatter.h中的注释来学习它们的API。它们有详细的注释,应该很容易理解。
SLogLib使用cmake(http://www.cmake.org)生成构建工具所需的文件,如GNU Make、Visual Studio、XCode等。如果是cmake新手,应该阅读Running CMake教程(http://www.cmake.org/runningcmake/)。
可以在cmake中配置以下变量:
SLogLib已在Windows上的Visual Studio 2010和2013、Linux上的g++以及OSX上的XCode 6和g++上进行了测试。
如果想通过创建自己的日志设备或格式化器来扩展SLogLib,应该阅读本节以了解SLogLib的工作原理。SLogLib有三个主要组件:一个消息结构、将消息转换为std::strings的格式化器,以及将std::strings写入底层设备的日志设备。以下是SLogLib的整体架构:
消息是核心数据:
消息结构是核心数据,它被格式化为字符串并写入设备。它有以下字段:
格式化器将消息格式化为字符串:
所有格式化器都是从AbstractFormatter类派生的。如果想编写一个新的格式化器,应该继承AbstractFormatter并覆盖FormatMessage()函数。有四个预定义的格式化器:
NullFormatter简单地输出用户消息。InfoFormatter、ErrorFormatter和DetailedFormatter只格式化在它们的消息级别或以下的消息。