C++:日志库log4cplus 2.0的使用说明

以前在做java开发时一直都在用log4j,它配置灵活,功能强大。如果C++中也存在类似配置的日志库,则可以省去不少学习的时间。在C++中的确有这样的一些库,本文就拿其中用的最多的log4cplus来讲讲如何使用它。

项目主页:
https://sourceforge.net/p/log4cplus/wiki/Home/
https://github.com/wilx/log4cplus

可以从以上两个地址中下载最新的文件,本文使用的最新版本是log4cplus-2.0.2。下载完成并解压后,可以在log4cplus-2.0.2目录下找到msvc14目录,进入后找到log4cplus.sln文件。先在确认已Visual Studio 2015以上版本,然后双击打开此文件,就会看到如下内容:

其中,log4cplus可以生成动态库,log4cplusS可以生成静态库。本文要在64位系统中生成测试用的静态库,所以配置成Debug x64,字符集设置成Unicode。然后编译log4cplusS,会在msvc14\x64\bin.Debug下生成log4cplusSD.lib文件。

下面是测试代码:

#include <vector>
#include <thread>
#include <chrono>
#include <string>
#include <memory>
#include <ctime>
#include <iomanip>

#include <log4cplus/logger.h>
#include <log4cplus/loggingmacros.h>
#include <log4cplus/configurator.h>
#include <log4cplus/initializer.h>
#include <log4cplus/loglevel.h>
#include <log4cplus/ndc.h>

using namespace std;
using std::chrono::system_clock;

using namespace log4cplus;
using namespace log4cplus::helpers;

string getTime() {
	system_clock::time_point tp = system_clock::now();
	time_t raw_time = system_clock::to_time_t(tp);
	struct tm  *timeinfo = std::localtime(&raw_time);

	std::stringstream ss;
	ss << std::put_time(timeinfo, "%Y-%m-%d %H:%M:%S");

	return ss.str();
}

void doTestRun(int i) {
	static log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("main"));

	string threadName = "doRun-" + to_string(i);
	// 使用NDC给线程设置名称
	log4cplus::NDCContextCreator _ndc(LOG4CPLUS_STRING_TO_TSTRING(threadName));

	while (true) {
		this_thread::sleep_for(3s);
		// 如果不加u8,日志文件会是GB2312格式
		string info = u8"你好:" + getTime();

		LOG4CPLUS_WARN(logger, LOG4CPLUS_STRING_TO_TSTRING(info));
	}
}

int main() {
	log4cplus::Initializer initializer;
	PropertyConfigurator pc(LOG4CPLUS_TEXT("log4cplus.properties"));
	pc.configure();

	vector<std::thread> threadVector;

	for (int i = 0; i < 5; i++) {
		threadVector.emplace_back(doTestRun, i);
	}

	for (vector<std::thread>::iterator itr = threadVector.begin(); itr != threadVector.end(); itr++) {
		itr->join();
	}

	return 0;
}

配置文件log4cplus.properties中的内容:

log4cplus.rootLogger=DEBUG, STDOUT

log4cplus.appender.STDOUT=log4cplus::ConsoleAppender
log4cplus.appender.STDOUT.layout=log4cplus::TTCCLayout

# 对ALL_MSGS使用异步Appender
log4cplus.appender.ALL_MSGS=log4cplus::AsyncAppender
# 异步Appender的队列大小
log4cplus.appender.ALL_MSGS.QueueLimit=10000
# 异步Appender中具体使用RollingFileAppender作为写文件的FileAppender
log4cplus.appender.ALL_MSGS.Appender=log4cplus::DailyRollingFileAppender
# 应用重新启动后是要清空日志文件再写入,还是要接在日志文件后面接着写入
log4cplus.appender.ALL_MSGS.Appender.Append=false
# 设置FileAppender的缓存大小
log4cplus.appender.ALL_MSGS.Appender.BufferSize=10000
# 达到缓存上限后是否立即写入
log4cplus.appender.ALL_MSGS.Appender.ImmediateFlush=true
# 写的文件路径和文件名
log4cplus.appender.ALL_MSGS.Appender.File=d:/Temp/test.log
# 设置每个日志文件的最大容量
log4cplus.appender.ALL_MSGS.Appender.MaxFileSize=250KB
# 日志文件达到最大容量后,重命名文件以备份,设置最大备份日志文件数
log4cplus.appender.ALL_MSGS.Appender.MaxBackupIndex=10
# 指定日志文件回滚周期
log4cplus.appender.ALL_MSGS.Appender.Schedule=MINUTELY
# 当日志文件达到回滚周期时,则重新生成新的日志文件,旧的日志文件会加上.%Y%m%d_%H%M后缀
log4cplus.appender.ALL_MSGS.Appender.DatePattern=%Y%m%d_%H%M
# 设置输出使用的locale
# log4cplus.appender.ALL_MSGS.Appender.Locale=en_US.UTF-8
# 自定义FileAppender的输出格式
log4cplus.appender.ALL_MSGS.Appender.layout=log4cplus::PatternLayout
# 自定义FileAppender的输出格式的样式
log4cplus.appender.ALL_MSGS.Appender.layout.ConversionPattern=%D{%Y-%m-%d %H:%M:%S.%q}%5p[%5t|%x][%l][%c]- %m%n


# category为main的日志
log4cplus.logger.main=DEBUG, ALL_MSGS
log4cplus.additivity.main=false

代码运行结果保存为UTF-8格式:

2018-10-18 18:41:00.898 WARN[29816|doRun-3][d:\vc_projects\log4cplus.cpp:45][main]- 你好:2018-10-18 18:41:00
2018-10-18 18:41:00.902 WARN[18180|doRun-4][d:\vc_projects\log4cplus.cpp:45][main]- 你好:2018-10-18 18:41:00
2018-10-18 18:41:00.902 WARN[17704|doRun-0][d:\vc_projects\log4cplus.cpp:45][main]- 你好:2018-10-18 18:41:00
2018-10-18 18:41:00.904 WARN[28388|doRun-2][d:\vc_projects\log4cplus.cpp:45][main]- 你好:2018-10-18 18:41:00
2018-10-18 18:41:00.905 WARN[  5164|doRun-1][d:\vc_projects\log4cplus.cpp:45][main]- 你好:2018-10-18 18:41:00

在代码中通过NDC给每个新创建的线程设置了线程名,这样通过%x和%t可以在日志中同时打印出线程名和线程编号。

PatterLayout的完整说明可在如下地址找到:
https://log4cplus.sourceforge.io/docs/html/classlog4cplus_1_1PatternLayout.html

log4cplus是通过如下的宏生成日志的:

    LOG4CPLUS_TRACE (logger, "printMessages()");
    LOG4CPLUS_DEBUG (logger, "This is a DEBUG message");
    LOG4CPLUS_INFO (logger, "This is a INFO message");
    LOG4CPLUS_WARN (logger, "This is a WARN message");
    LOG4CPLUS_ERROR (logger, "This is a ERROR message");
    LOG4CPLUS_FATAL (logger, "This is a FATAL message");

另外,需要注意才下几点:
1.打印字符串常量要使用LOG4CPLUS_TEXT,打印string要使用LOG4CPLUS_STRING_TO_TSTRING。
2.编译代码时要使用Unicode字符集。
3.使用thread创建的线程只有线程编号,没有线程名,可以使用NDC给线程设置一个名字,这样查看日志时方便。

参考文档

CodeExamples
Log4cplus选型和使用指南
log4cplus 使用方法 配置

猜你喜欢

转载自blog.csdn.net/netyeaxi/article/details/83149255