65.9K
CodeProject 正在变化。 阅读更多。
Home

极简日志记录器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (14投票s)

2009年4月28日

CPOL

3分钟阅读

viewsIcon

72478

downloadIcon

2001

一个单一头文件、跨平台、线程安全的日志记录工具。

引言

这是一个易于使用的跨平台和线程安全的日志记录工具的实现。

背景

日志记录是编程中的一项基本技术。有时它还是唯一的诊断工具。 毫不奇怪,有许多不同的日志记录库。 它们提供了对各种目标(大多数你从未听说过)的日志记录,几十个日志类别(如“警告”、“严重警告”、“几乎错误”、“严重错误”、“地球的终结”),全面的配置和输出格式,垂直起飞(我确定我记得一个这样的日志库)等等。 我确信有项目确实需要所有这些功能。 不需要它们的人会编写自己的日志记录。

有一天,当我决定扔掉其中一个全面的日志库(因为它有一个4页的功能列表但不是线程安全的),我尝试编写一个简单的日志记录器,并且对它有以下要求

  • 记录到日志文件和控制台(如果存在)
  • 记录错误、普通日志消息和调试消息(能够关闭不重要的类别)
  • 简单性:仅一个头文件
  • 可用性:类似 printf() 的格式化,以及能够自动将函数名(或 class_name::function_name)放在日志消息的开头
  • 日志记录应该是线程安全的
  • 该库应该在 Windows 和 Linux 下都能正常工作(未在 MacOS 下测试,但认为那里没有理由它不能工作)
  • 日志记录应该尽可能高效,并且我需要能够将其关闭

这已经是该库的第二个版本,其中包含一些改进和补充。 进一步的开发也已计划,例如,下一个版本将包括日志消息格式配置。 如果您看到如何改进此库,或者您需要未实现的功能 - 请不要犹豫,在下面的评论中写下。

Using the Code

您需要将 "logger.h" 包含到您的源代码中(预编译头文件是最合适的地方),设置日志输出的文件名,然后开始记录,记录,记录。:) 看起来像这样

#include "logger.h"

int main()
{
	logging::set_output("filename.log");
	logging::set_minimal_category(logging::cat_info); 	// to filter out 
							// debug messages

	log_error("to log w/o logging place info, uses %s format", "printf()");
	LOG("to log with function name and with single %s", "argument");
	log_debug("debug message shouldn't appear because of category filter");

    return 0;
} 

输出看起来像这样

08:30:20:609  3412 ERROR: to log w/o logging place info, uses printf() format
08:30:20:609  3412 info: main: to log with function name and with single argument
08:30:20:625  3412 info: main: this long log message should be truncated 
				because of too short buf

格式为

HH:MM:SS:FFF thread_id log_category: optional_function_name: log-message

LOGLOG_ERRORLOG_DEBUG 将函数名放在发生日志记录的地方。

要关闭日志记录,请在包含 "logger.h" 之前定义 LOGGING_DISABLED

顺便说一句,这些宏非常有用,例如,如果您有一个函数...

void DoSomething(ID item_id) 

...您可以像这样记录它...

LOG("id = %d", item_id)

这已经足够了,因为函数名将被自动添加。

默认情况下,日志消息格式化缓冲区为 4096 个字符长,这在大多数情况下应该足够了。 但是您可以使用 logging::set_buffer_size(size_t new_size) 来更改此设置。

关注点

为了提供可移植性,我使用了 Boost。 如果您仍未使用 Boost 库,这是一个很好的开始机会,它们将“提升”您的 C++ 编程性能。

效率通过优化输出格式化的内存分配和无锁输出缓冲区的同步来实现 - 将其保存在线程本地存储中。 选择 printf() 格式化风格而不是更现代且更健壮的 boost::format 也是为了获得更好的性能。

致谢

我要感谢我的朋友 Sviatoslav Danyliv (aka Dans.Lviv.Ua) 和所有评论过这个库的人,感谢他们的帮助。

历史

  • 2009 年 4 月 28 日:初始发布
  • 2009年5月9日:版本 2.0
© . All rights reserved.