SLogLib: 跨平台日志库指南

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

一些重要点:

  • SLogLib自动管理设备和格式化器,所以一旦将它们传递给SLogLib,就不要删除它们。
  • 格式化器只能在构造时分配给设备,之后不能更改。
  • 格式化器不能在设备之间共享。每个设备必须有一个唯一的格式化器。
  • 可以使用Disable()临时禁用日志设备。要再次启用,请使用Enable()。

SLogLib API

宏:

#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

SLogLib使用cmake(http://www.cmake.org)生成构建工具所需的文件,如GNU Make、Visual Studio、XCode等。如果是cmake新手,应该阅读Running CMake教程(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有三个主要组件:一个消息结构、将消息转换为std::strings的格式化器,以及将std::strings写入底层设备的日志设备。以下是SLogLib的整体架构:

消息是核心数据:

消息结构是核心数据,它被格式化为字符串并写入设备。它有以下字段:

  • 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只格式化在它们的消息级别或以下的消息。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485