SLogLib:一个易于使用、完全可定制且可扩展的跨平台日志库






4.47/5 (8投票s)
SLogLib 是一个易于使用、完全可定制且可扩展的跨平台日志库。
引言
SLogLib 是一个易于使用、完全可定制且可扩展的跨平台日志库。SLogLib 的重要特性包括:
- 支持用户自定义消息格式。
- 支持多种日志输出设备,包括控制台、文件和控件。
- 支持调用栈。
入门
以下是开始使用 SLogLib 所需的最少代码:
#include "SLogLib/SLogLib"
void main()
{
// Add these lines at the beginning of your program.
// The devices and formatters are automatically deleted by SLogLib.
using namespace SLogLib;
addLoggingDevice(new ConsoleLogger(new NullFormatter)); // LINE 1
addLoggingDevice(new FileLogger("foo.log", new DetailedFormatter)); // LINE 2
// The following line writes the message to both console and file.
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 在每条消息后不添加换行符。您可以自己为每条消息添加换行符,或者在 NullFormatter 的构造函数中传递 AppendNewLine 参数,以在每条消息后自动添加换行符。
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
几个要点
- SLogLib 会自动管理设备和格式化器,因此在将它们传递给 SLogLib 后请勿删除它们。
- 格式化器只能在构造时分配给设备,之后不能更改。
- 格式化器不能在设备之间共享。每个设备都必须有一个唯一的格式化器。
- 可以使用 Disable() 临时禁用一个日志设备。要重新启用,请使用 Enable()。
SLogLib API
宏
#define SLOGLIB_DISABLE_LOGGING
在编译时禁用所有日志代码。这可用于在生产版本中完全禁用日志。最好通过编译器参数定义此选项。如果您希望在运行时禁用日志,请使用 disableLogging() 和 enableLogging()。
#define SLOGLIB_LOG_MESSAGE(level, msg)
将指定级别的消息写入所有启用的日志设备。
#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)
上述方便宏会在预定义级别写入消息。
#define SLOGLIB_ADD_TO_CALLSTACK
将调用此宏的函数添加到当前调用栈。它可用于在调试时为重要函数构建调用栈。调用栈包含在 Message 中,并且可以写入日志设备。
函数
以下所有函数都包含在 SLogLib 命名空间中。
void SLogLib::addLoggingDevice(AbstractLoggingDevice* device);
将指定的日志设备添加到日志设备列表中。
void SLogLib::removeLoggingDevice(AbstractLoggingDevice* device);
void SLogLib::removeLoggingDevice(const std::string& name);
从日志设备列表中删除一个日志设备。
AbstractLoggingDevice* SLogLib::queryLoggingDevice(const std::string& name);
获取日志设备的指针。请注意,返回的指针不得被删除或更改。如果您想删除现有的日志设备,请使用 removeLoggingDevice()。
void SLogLib::writeMessage(const std::string& fileName,
const std::string& funcName,
unsigned int lineNo,
unsigned int level,
const std::string& msg);
将消息写入所有活动的日志设备。前三个参数必须是消息记录的源文件名、函数名和行号。最后两个参数是级别和要写入的消息。您无需直接调用此函数;SLOGLIB_LOG_MESSAGE 在自动添加文件名、函数名和行号后会在内部调用此函数。
void SLogLib::disableLogging();
void SLogLib::enableLogging();
bool SLogLib::isLoggingEnabled();
在运行时禁用和启用日志。在禁用日志期间,所有消息都会被忽略,并且在重新启用日志后也不会写入日志设备。
注释
您还应该阅读 AbstractLoggingDevice.h 和 AbstractFormatter.h 中的注释,以了解它们的 API。它们注释良好,应该易于理解。
构建 SLogLib
SLogLib 使用 cmake (http://www.cmake.org) 来生成构建工具(如 GNU Make、Visual Studio、XCode 等)所需的文件。如果您是 cmake 新手,应该阅读 Running CMake tutorial (http://www.cmake.org/runningcmake/)。
您可以在 cmake 中配置以下变量:
- SLOGLIB_DEBUG_POSTFIX (string):添加到调试构建库名称的后缀(默认为 d)。
- SLOGLIB_BUILD_EXAMPLES (bool):构建示例(默认为 true)。
- SLOGLIB_BUILD_QT_EXAMPLES (bool):构建 Qt 示例(默认为 false)。
- SLOGLIB_USE_QT_VERSION (list):选择 Qt 版本:Qt4 或 Qt5(默认为 Qt5)。
SLogLib 已在 Windows 上使用 Visual Studio 2010 和 2013,在 Linux 上使用 g++,在 OSX 上使用 XCode 6 和 g++ 进行了测试。
SLogLib 内部结构
如果您希望通过创建自己的日志设备或格式化器来扩展 SLogLib,应该阅读本节以了解 SLogLib 的工作原理。SLogLib 包含三个主要组件:Message 结构体、将 Message 转换为 std::string 的格式化器,以及将 std::string 写入底层设备的日志设备。SLogLib 的整体架构如下:
Message 是核心数据
Message 结构体是核心数据,它会被格式化为字符串并写入设备。它包含以下字段:
- mUserMessage:用户记录的消息。
- mDateTime:记录消息时的本地日期和时间。
- mLevel:用于将消息分类到不同级别。格式化器可以使用消息级别进行过滤,只格式化某些类型的消息并忽略其他消息。例如,您可能只想将错误消息写入控制台,而将所有类型的消息写入文件。以下消息级别定义如下:
- MESSAGE_LEVEL_INFO
- MESSAGE_LEVEL_WARNING
- MESSAGE_LEVEL_ERROR
- MESSAGE_LEVEL_DEBUG
- MESSAGE_LEVEL_DETAIL
- mCallstack:当前调用栈。默认情况下,它只包含一个条目:消息记录的行。但是,通过将 SLOGLIB_ADD_TO_CALLSTACK 添加到您希望包含在调用栈中的所有函数,可以生成更完整的调用栈。
- mProcessID:记录消息的进程 ID。
- mThreadID:记录消息的线程 ID。
格式化器将消息格式化为字符串
所有格式化器都派生自 AbstractFormatter 类。如果您想编写新的格式化器,应该继承自 AbstractFormatter 并重写 FormatMessage() 函数。有四种预定义的格式化器:
- NullFormatter
- InfoFormatter
- ErrorFormatter
- DetailedFormatter
NullFormatter 仅输出用户消息。InfoFormatter、ErrorFormatter 和 DetailedFormatter 只格式化与其消息级别相等或更低的消息。
日志设备将字符串写入设备
所有日志设备都继承自 AbstractLoggingDevice。SLogLib 包含一个 ConsoleLogger (std::cout) 和 FileLogger (std::ofstream)。要创建新的日志设备,只需继承自 AbstractLoggingDevice 并重写 _WriteMessage()。更多详情请参阅 AbstractLoggingDevice.h。
Github
SLogLib 托管在 Github 上:https://github.com/saurabhg17/SLogLib。