首页 > 代码库 > log4cplus简单封装

log4cplus简单封装

封装的最后结果像下面这样:

主要封装的功能,提供日志等级、日志文件大小设置,滚动写多个文件,文件个数可设置,提供日志服务器(用了Windows的CreateThread,如果在其他环境下用对应的线程工具即可)

#include "robotlog.h"

int main()
{
	//ROBOTLOG_API RobotLog(
	//	const wstring& file_name = L"..\\log\\robot.log",
	//	const wstring&  number_of_file = L"10",
	//	const wstring&  size_of_log_file = L"8388608",//一个文件8MB
	//	const wstring&  log_level = L"0",
	//	const wstring& ip = L"localhost",
	//	const wstring&  port = L"20009"
	//	);


	RobotLog* logger = new RobotLog(L".\\robot.txt",L"3",L"8388608",L"0",L"172.16.107.197",L"20009");
	cout<<"main write log"<<endl;
	//for (int i=0;i<10;i++)
	//{
		logger->write_debug("hello 1 debug");
	//	logger->write_error("hello 2 error");
	//	logger->write_infor("hello 4 infor");
	//	logger->write_trace("hello 5 trace");
	//}
	cout<<"server listenning...."<<endl;
	RobotServerLogThread* thrd = new RobotServerLogThread(L"20009");
	thrd->run_log_server();

	cout<<"after run log server"<<endl;
}

输出日志:

2014-12-31 10:36:34 INFO - 不连接设备:HIKCamera [RobotLog.cpp:87]
2014-12-31 10:36:34 INFO - 不连接设备:FlirServer [RobotLog.cpp:87]
2014-12-31 10:36:34 INFO - 不连接设备:Flir [RobotLog.cpp:87]
2014-12-31 10:36:34 INFO - 允许连接设备:PanTilt [RobotLog.cpp:87]
2014-12-31 10:37:39 ERROR - PanTilt连接失败!192.168.10.14 [RobotLog.cpp:82]
2014-12-31 10:37:39 INFO - 不连接设备:Chasis [RobotLog.cpp:87]
2014-12-31 10:37:39 INFO - 不连接设备:AudioRecord [RobotLog.cpp:87]
2014-12-31 10:37:39 DEBUG - 日志服务启动:RobotServerLogThread(20009) [RobotLog.cpp:109]
2014-12-31 11:17:56 INFO - 不连接设备:HIKCamera [RobotLog.cpp:87]
2014-12-31 11:17:56 INFO - 不连接设备:FlirServer [RobotLog.cpp:87]
2014-12-31 11:17:56 INFO - 不连接设备:Flir [RobotLog.cpp:87]
2014-12-31 11:17:56 INFO - 允许连接设备:PanTilt [RobotLog.cpp:87]
2014-12-31 11:19:01 ERROR - PanTilt连接失败!192.168.10.14 [RobotLog.cpp:82]
2014-12-31 11:19:01 INFO - 不连接设备:Chasis [RobotLog.cpp:87]
2014-12-31 11:19:01 INFO - 不连接设备:AudioRecord [RobotLog.cpp:87]
2014-12-31 11:19:01 DEBUG - 日志服务启动:RobotServerLogThread(20009) [RobotLog.cpp:109]
2014-12-31 11:19:19 DEBUG - 云台向上 GetPanTilt()->up speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:19:19 DEBUG - 云台停止向上运动 [RobotLog.cpp:92]
2014-12-31 11:19:20 DEBUG - 云台向下 GetPanTilt()->down speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:19:20 DEBUG - 云台停止向下运动 [RobotLog.cpp:92]
2014-12-31 11:19:20 DEBUG - 云台向右 GetPanTilt()->right speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:19:20 DEBUG - 云台停止向右运动 [RobotLog.cpp:92]
2014-12-31 11:19:21 DEBUG - 云台向左 GetPanTilt()->left speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:19:21 DEBUG - 云台停止向左运动 [RobotLog.cpp:92]
2014-12-31 11:20:09 INFO - 不连接设备:HIKCamera [RobotLog.cpp:87]
2014-12-31 11:20:09 INFO - 不连接设备:FlirServer [RobotLog.cpp:87]
2014-12-31 11:20:09 INFO - 不连接设备:Flir [RobotLog.cpp:87]
2014-12-31 11:20:09 INFO - 允许连接设备:PanTilt [RobotLog.cpp:87]
2014-12-31 11:21:13 ERROR - PanTilt连接失败!192.168.10.14 [RobotLog.cpp:82]
2014-12-31 11:21:13 INFO - 不连接设备:Chasis [RobotLog.cpp:87]
2014-12-31 11:21:13 INFO - 不连接设备:AudioRecord [RobotLog.cpp:87]
2014-12-31 11:21:13 DEBUG - 日志服务启动:RobotServerLogThread(20009) [RobotLog.cpp:109]
2014-12-31 11:21:26 DEBUG - 云台向上 GetPanTilt()->up speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:21:26 DEBUG - 云台停止向上运动 [RobotLog.cpp:92]
2014-12-31 11:21:26 DEBUG - 云台向下 GetPanTilt()->down speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:21:26 DEBUG - 云台停止向下运动 [RobotLog.cpp:92]
2014-12-31 11:21:27 DEBUG - 云台向左 GetPanTilt()->left speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:21:27 DEBUG - 云台停止向左运动 [RobotLog.cpp:92]
2014-12-31 11:21:28 DEBUG - 云台向右 GetPanTilt()->right speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:21:28 DEBUG - 云台停止向右运动 [RobotLog.cpp:92]
2014-12-31 11:21:30 DEBUG - 云台左上 GetPanTilt()->upLeft speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:21:30 DEBUG - 云台停止左上运动 [RobotLog.cpp:92]
2014-12-31 11:21:31 DEBUG - 云台右上 GetPanTilt()->upRight speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:21:31 DEBUG - 云台停止右上运动 [RobotLog.cpp:92]
2014-12-31 11:21:32 DEBUG - 云台左下 GetPanTilt()->downLeft speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:21:32 DEBUG - 云台停止左下运动 [RobotLog.cpp:92]
2014-12-31 11:21:33 DEBUG - 云台右下 GetPanTilt()->downRight speed_value:30 [RobotLog.cpp:92]
2014-12-31 11:21:33 DEBUG - 云台停止右下运动 [RobotLog.cpp:92]
2014-12-31 11:45:28 INFO - 不连接设备:HIKCamera [RobotLog.cpp:87]
2014-12-31 11:45:28 INFO - 不连接设备:FlirServer [RobotLog.cpp:87]
2014-12-31 11:45:28 INFO - 不连接设备:Flir [RobotLog.cpp:87]
2014-12-31 11:45:28 INFO - 允许连接设备:PanTilt [RobotLog.cpp:87]
2014-12-31 11:46:33 ERROR - PanTilt连接失败!192.168.10.14 [RobotLog.cpp:82]
2014-12-31 11:46:33 INFO - 不连接设备:Chasis [RobotLog.cpp:87]
2014-12-31 11:46:33 INFO - 不连接设备:AudioRecord [RobotLog.cpp:87]
2014-12-31 11:46:33 DEBUG - 日志服务启动:RobotServerLogThread(20009) [RobotLog.cpp:109]
2014-12-31 12:22:42 INFO - 不连接设备:HIKCamera [RobotLog.cpp:87]
2014-12-31 12:22:42 INFO - 不连接设备:FlirServer [RobotLog.cpp:87]
2014-12-31 12:22:42 INFO - 不连接设备:Flir [RobotLog.cpp:87]
2014-12-31 12:22:42 INFO - 允许连接设备:PanTilt [RobotLog.cpp:87]
2014-12-31 12:23:47 ERROR - PanTilt连接失败!192.168.10.14 [RobotLog.cpp:82]
2014-12-31 12:23:47 INFO - 不连接设备:Chasis [RobotLog.cpp:87]
2014-12-31 12:23:47 INFO - 不连接设备:AudioRecord [RobotLog.cpp:87]
2014-12-31 12:23:47 DEBUG - 日志服务启动:RobotServerLogThread(20009) [RobotLog.cpp:109]
2014-12-31 12:23:59 DEBUG - 按下了A,a键底盘左移 speed_value:0.4 [RobotLog.cpp:92]
2014-12-31 12:23:59 DEBUG - 松开了A,a键底盘停止运动 [RobotLog.cpp:92]

下面是具体的封装

头文件RobotLog.h

#pragma once

#ifdef ROBOTLOG_EXPORTS     
#define ROBOTLOG_API __declspec(dllexport)      
#else     
#define ROBOTLOG_API __declspec(dllimport)      
#endif   

#include <string>
using namespace std;

#include "log4cplus/logger.h"
#include <log4cplus/consoleappender.h> //输出到控制台
#include <log4cplus/fileappender.h> //输出到文件
#include "log4cplus/layout.h"
#include "log4cplus/loggingmacros.h" //LOG4CPLUS_WARN


#include <cstdlib>
#include <iostream>
#include <log4cplus/configurator.h>
#include <log4cplus/socketappender.h>
#include <log4cplus/helpers/socket.h>
#include <log4cplus/thread/threads.h>
#include <log4cplus/spi/loggingevent.h>

using namespace log4cplus;
using namespace log4cplus::helpers;
typedef log4cplus::helpers::Socket RobotSocket;

#include <windows.h>  
#include <iostream>  
#include <vector>  
#include <string>  
#include <sstream>  
#include <algorithm>  
#include <iterator>  
using namespace std;  

template<typename Result,typename Para>  
Result lexical_cast(Para para)  
{  
	wstringstream ss;  
	ss<<para;  
	Result result;  
	ss>>result;  
	return result;  
}  

DWORD ROBOTLOG_API WINAPI ReceiveFunc(LPVOID p);
// #日志文件级别:0:ERROR,1:INFO,2:DEBUG,3:TRACE,默认值为0
class  RobotLog : public Logger
{
public:
	ROBOTLOG_API RobotLog(
		const wstring& file_name = L"..\\log\\robot.log",
		const wstring&  number_of_file = L"10",
		const wstring&  size_of_log_file = L"8388608",//一个文件8MB
		const wstring&  log_level = L"3",
		const wstring& ip = L"localhost",
		const wstring&  port = L"20009"
		);
	ROBOTLOG_API ~RobotLog(void);

	ROBOTLOG_API void write_error(const string&);
	ROBOTLOG_API void write_infor(const string&);
	ROBOTLOG_API void write_debug(const string&);
	ROBOTLOG_API void write_trace(const string&);
private:
	wstring file_name ;
	int number_of_file ;
	int size_of_log_file ;
	int log_level ;// #日志文件级别:0:ERROR,1:INFO,2:DEBUG,3:TRACE,默认值为0
	wstring ip;
	int port;
	Logger logger;
};

class RobotServerLogThread : public log4cplus::thread::AbstractThread
{
public:
	ROBOTLOG_API RobotServerLogThread(const wstring& port);
	ROBOTLOG_API RobotServerLogThread(log4cplus::helpers::Socket clientsock);
	ROBOTLOG_API ~RobotServerLogThread();
	ROBOTLOG_API virtual void run();
	ROBOTLOG_API void run_log_server();
private:
	int port;
	log4cplus::helpers::Socket m_clientsock;
};

源文件

#include "RobotLog.h"
#include "log4cplus/logger.h"
#include <log4cplus/consoleappender.h> //输出到控制台
#include <log4cplus/fileappender.h> //输出到文件
#include "log4cplus/layout.h"
#include "log4cplus/loggingmacros.h" //LOG4CPLUS_WARN

RobotLog::RobotLog(
	const wstring& file_name,
	const wstring&  number_of_file,
	const wstring&  size_of_log_file ,
	const wstring&  log_level,
	const wstring& ip ,
	const wstring&  port)
{
	this->file_name = file_name;
	this->number_of_file = lexical_cast<int>(number_of_file);
	this->size_of_log_file = lexical_cast<int>(size_of_log_file);
	this->log_level = lexical_cast<int>(log_level);
	this->ip = ip;
	this->port = lexical_cast<int>(port);
	//SharedObjectPtr<Appender> append(new ConsoleAppender());
	//RollingFileAppender::RollingFileAppender(const log4cplus::tstring& filename,
	//	long maxFileSize,
	//	int maxBackupIndex,
	//	bool immediateFlush)

	//SharedObjectPtr<Appender> append(new RollingFileAppender(L"robot.log",5*1024,10,1));//5KB每个日志。小于200KB自动使用200KB
	SharedObjectPtr<Appender> append(new RollingFileAppender(
		this->file_name.c_str(),
		this->size_of_log_file,
		this->number_of_file,
		1));//5KB每个日志。小于200KB自动使用200KB
	//append->setName(L"append for test");
	/* step 2: Instantiate a layout object 输出格式 */
	std::wstring pattern = L"%D %p - %m [%l]%n";
	//std::wstring pattern = L"%d{%x %X} %p - %m [%l]%n";

	//std::wstring pattern = L"%d{%c} %p - %m [%l]%n";
	std::auto_ptr<Layout> layout(new PatternLayout(pattern));
	/* step 3: Attach the layout object to the appender 格式绑定到介质 */
	append->setLayout( layout );
	/* step 4: Instantiate a logger object 日志输出对象*/
	//this->logger = Logger::getInstance(L"robotlog");
	this->logger = Logger::getRoot();
	/* step 5: Attach the appender object to the logger  输出信息绑定到日志输出对象*/
	logger.addAppender(append);
	/* step 6: Set a priority for the logger  设置日志输出对象的级别*/


	// #日志文件级别:0:ERROR,1:INFO,2:DEBUG,3:TRACE,默认值为0
	if (this->log_level == 0)
	{
		logger.setLogLevel(log4cplus::ERROR_LOG_LEVEL);
	}
	else if (this->log_level == 1)
	{
		logger.setLogLevel(log4cplus::INFO_LOG_LEVEL);
	}
	else if (this->log_level == 2)
	{
		logger.setLogLevel(log4cplus::DEBUG_LOG_LEVEL);
	}
	else if (this->log_level == 3)
	{
		logger.setLogLevel(log4cplus::TRACE_LOG_LEVEL);
	}
	else
	{
		logger.setLogLevel(log4cplus::ERROR_LOG_LEVEL);
	}

}


RobotLog::~RobotLog(void)
{

}
void RobotLog::write_error(const string&  s)
{
	LOG4CPLUS_ERROR(this->logger,s.c_str());
}

void RobotLog::write_infor(const string& s)
{
	LOG4CPLUS_INFO(this->logger,s.c_str());
}

void RobotLog::write_debug(const string& s)
{
	LOG4CPLUS_DEBUG(this->logger,s.c_str());
}

void RobotLog::write_trace(const string& s)
{
	LOG4CPLUS_TRACE(this->logger,s.c_str());
}

RobotServerLogThread::RobotServerLogThread(log4cplus::helpers::Socket clientsock)
	: m_clientsock(clientsock) 
{
	LOG4CPLUS_INFO(Logger::getRoot(),"接收客户端写日志连接");
}

RobotServerLogThread::RobotServerLogThread(const wstring& port)
{
	this->port= lexical_cast<int>(port);
	LOG4CPLUS_DEBUG(Logger::getRoot(),"日志服务启动:RobotServerLogThread("<<port<<")");

}

RobotServerLogThread::~RobotServerLogThread()
{
	LOG4CPLUS_DEBUG(Logger::getRoot(),"~RobotServerLogThread()");
}

void RobotServerLogThread::run()
{
	while(1) {
		//LOG4CPLUS_ERROR(Logger::getRoot(),"read to read log 7");
		if(!m_clientsock.isOpen()) {
			delete this;
			return;
		}
		//LOG4CPLUS_ERROR(Logger::getRoot(),"read to read log");

		log4cplus::helpers::SocketBuffer msgSizeBuffer(sizeof(unsigned int));
		if(!m_clientsock.read(msgSizeBuffer)) {
			//LOG4CPLUS_ERROR(Logger::getRoot(),"read failed 5");
			delete this;
			return;
		}
		//LOG4CPLUS_ERROR(Logger::getRoot(),"read success 2");
		unsigned int msgSize = msgSizeBuffer.readInt();

		log4cplus::helpers::SocketBuffer buffer(msgSize);
		if(!m_clientsock.read(buffer)) {
			//LOG4CPLUS_ERROR(Logger::getRoot(),"read failed 8");
			delete this;
			return;
		}
		//LOG4CPLUS_ERROR(Logger::getRoot(),"read success 3");
		log4cplus::spi::InternalLoggingEvent event1
			= log4cplus::helpers::readFromBuffer(buffer);
  
		Logger::getRoot().callAppenders(event1);
		//LOG4CPLUS_ERROR(Logger::getRoot(),"read success 4");
	}
}

void RobotServerLogThread::run_log_server()
{
	HANDLE handle = CreateThread(NULL, 0, ReceiveFunc, (LPVOID*)&port, 0, NULL);  
}


DWORD WINAPI ReceiveFunc(LPVOID p)
{

	int port = *(int*)p;

	ServerSocket serverSocket(port);
	while(1) {

		RobotServerLogThread *thr = new RobotServerLogThread(serverSocket.accept());
		thr->start();

	}

	return 0;
}

说明:从构造函数为L"something"来看,项目使用了Unicode编码,这个要在VS里面设置一下。


实现:

(1)由于这里封装成了dll,所以你的项目属性应该在预编译Preprocessor里面加上ROBOTLOG_EXPORTS

(2)这里使用了log4cplus的静态库作为功能支持,所以在项目的Input里面应该加上log4cplusS.lib,这里加的是log4cplus的Release版本,如果你需要Debug版本,请编译对应的版本,把生成的log4cplusSD.lib加入到你的项目里面。

(3)log4cplus的工程下载,编译生成动态或静态链接库:点击打开链接

(4)log4cplus的工程下载,也可以下载我提交的一个不是最新版的版本:点击打开链接,用VS有几个地方要注意,编码格式,生成动态库的格式,依赖库的格式,等自己要知道。


log4cplus简单封装