综合

log4cxx配置使用(二)

导读: 

一、配置文件的例子

log4j.rootLogger=DEBUG,lib
log4j.appender.lib=org.apache.log4j.ConsoleAppender
log4j.appender.lib.Threshold=DEBUG
log4j.appender.lib.File=./log/output.log
log4j.appender.lib.Append=true
log4j.appender.lib.layout=org.apache.log4j.PatternLayout
log4j.appender.lib.layout.ConversionPattern=[%-5p] %d %l : %m%n

下面就是一个简单的用配置文件配置log4cxx的代码

#include <log4cxx/logger.h>
#include <log4cxx/basicconfigurator.h>
#include <log4cxx/propertyconfigurator.h>
#include <log4cxx/helpers/exception.h>
#include <iostream>
int main()
{
        log4cxx::PropertyConfigurator::configureAndWatch("log4cxx.properties");
        log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("lib"));
        LOG4CXX_DEBUG(logger, "this is log4cxx test");
        return 0;
}

用配置文件的例子,网上可以找到很多,我这里要写的是用代码直接配置log4cxx。


二、头文件

#ifndef _aLogger_H__
#define _aLogger_H__

#include <log4cxx/logger.h>
#include <log4cxx/logstring.h>
#include <log4cxx/log4cxx.h>

#define _MSGBUF_MAX 4096

class aLogger
{
public:
	aLogger(const log4cxx::LogString &name="undefined");

	~aLogger();

	/**
 	 * @brief 添加控制台日志
 	 */
	void addConsoleLog(const log4cxx::LayoutPtr &layout);

	/**
 	 * @brief 移除控制台日志
 	 */
	void removeConsoleLog();

	/**
 	 * @brief 添加回滚文件日志
 	 */
	void addDailyLocalFileLog(const log4cxx::LayoutPtr &layout);

	/**
 	 * @brief 设置日志等级
 	 *
 	 * @param "TRACE" < "DEBUG" < "INFO" < "WARN" < "ERROR" < "FATAL"
 	 */
	bool setLevel(const log4cxx::LogString &level);
	
	/** 
	 * @brief trace 级别日志
	 * 
	 * @param format 参数
	 * @param ... 参数列表
	 */
	void trace(const char *format, ... );

	void debug(const char *format, ... );

	void info(const char *format, ... );

	void warn(const char *format, ... );

	void error(const char *format, ... );

	void fatal(const char *format, ... );

	/**
 	 * @brief 强制写日志,无视当前的日志级别
 	 */
	void forcelog(const log4cxx::LogString &level, const char *format, ... );

	/**
 	 * @brief 条件写错误日志,无视当前的日志级别
 	 */
	void assertlog(bool condition, const log4cxx::LogString &level, const char *format, ... );
private:
	log4cxx::LoggerPtr logger;
};

#endif


三、实现文件

#include <log4cxx/helpers/pool.h>
#include <log4cxx/basicconfigurator.h>
#include <log4cxx/dailyrollingfileappender.h>
#include <log4cxx/consoleappender.h>
#include <log4cxx/patternlayout.h>
#include <log4cxx/logmanager.h>
#include <cstdarg>
#include <cstdio>
#include "aLogger.h"

using namespace std;
using namespace log4cxx;

extern map<string, string> argMap;

aLogger::aLogger(const LogString &name)
{
	PatternLayoutPtr layout = new PatternLayout();
	LogString conversionPattern = LogString("%d{yyMMdd-HH:mm:ss} ") + name + LogString(" %5p: %m%n");
	layout->setConversionPattern(conversionPattern);

        logger = Logger::getRootLogger();
	logger->setLevel(Level::getTrace());
	addConsoleLog(layout);
	addDailyLocalFileLog(layout);
}

aLogger::~aLogger()
{
	LogManager::shutdown();
}

void aLogger::addConsoleLog(const LayoutPtr &layout)
{
	if (NULL == layout) return;

	helpers::Pool p;

	ConsoleAppenderPtr consoleAppender = new ConsoleAppender(LayoutPtr(layout));
	consoleAppender->setTarget(ConsoleAppender::getSystemOut());
	consoleAppender->activateOptions(p);
	consoleAppender->setEncoding("UTF-8");
	consoleAppender->setName("consoleAppender");

	BasicConfigurator::configure(AppenderPtr(consoleAppender));
}

void aLogger::removeConsoleLog()
{
	if (NULL == logger) return;
	ConsoleAppenderPtr consoleAppender = logger->getAppender("consoleAppender");
	if (NULL == consoleAppender) return;
	if (logger->isAttached(consoleAppender))
		logger->removeAppender(consoleAppender);
}

void aLogger::addDailyLocalFileLog(const LayoutPtr &layout)
{
	if (NULL == layout) return;

        helpers::Pool p;
	
	LogString LogPath;
	map<string, string>::const_iterator it = argMap.find("logPath");
	if (it == argMap.end())
		LogPath = "/tmp/out.log";
	else
		LogPath = it->second;
	
	DailyRollingFileAppenderPtr rollingfileAppender = new DailyRollingFileAppender();
	rollingfileAppender->setFile(LogPath);
        rollingfileAppender->setAppend(true);
        rollingfileAppender->setDatePattern("‘.‘yyyyMMdd-HH");
        rollingfileAppender->setLayout(LayoutPtr(layout));
        rollingfileAppender->activateOptions(p);
	rollingfileAppender->setEncoding("UTF-8");
	rollingfileAppender->setName("rollingfileAppender");

	BasicConfigurator::configure(AppenderPtr(rollingfileAppender));
}

bool aLogger::setLevel(const std::string &level)
{
	if (NULL == logger) return false;
	
	//如果字符串不符合要求,则返回DEBUG级别的指针
	LevelPtr pLevel = Level::toLevel(level);
        logger->setLevel(pLevel);
	return true;
}

void aLogger::trace(const char *format, ... )
{
	if (NULL == logger) return;

	char message[_MSGBUF_MAX];
	va_list ArgList;
	va_start(ArgList, format);
	vsnprintf(message, sizeof(message), format, ArgList);
	va_end(ArgList);
	LOG4CXX_TRACE(logger, message);
}

void aLogger::debug(const char *format, ... )
{
	if (NULL == logger) return;

	char message[_MSGBUF_MAX];
	va_list ArgList;
	va_start(ArgList, format);
	vsnprintf(message, sizeof(message), format, ArgList);
	va_end(ArgList);
	LOG4CXX_DEBUG(logger, message);
}

void aLogger::info(const char *format, ... )
{
	if (NULL == logger) return;

	char message[_MSGBUF_MAX];
	va_list ArgList;
	va_start(ArgList, format);
	vsnprintf(message, sizeof(message), format, ArgList);
	va_end(ArgList);
	LOG4CXX_INFO(logger, message);
}

void aLogger::warn(const char *format, ... )
{
	if (NULL == logger) return;

	char message[_MSGBUF_MAX];
	va_list ArgList;
	va_start(ArgList, format);
	vsnprintf(message, sizeof(message), format, ArgList);
	va_end(ArgList);
	LOG4CXX_WARN(logger, message);
}

void aLogger::error(const char *format, ... )
{
	if (NULL == logger) return;

	char message[_MSGBUF_MAX];
	va_list ArgList;
	va_start(ArgList, format);
	vsnprintf(message, sizeof(message), format, ArgList);
	va_end(ArgList);
	LOG4CXX_ERROR(logger, message);
}

void aLogger::fatal(const char *format, ... )
{
	if (NULL == logger) return;

	char message[_MSGBUF_MAX];
	va_list ArgList;
	va_start(ArgList, format);
	vsnprintf(message, sizeof(message), format, ArgList);
	va_end(ArgList);
	LOG4CXX_FATAL(logger, message);
}

void aLogger::forcelog(const log4cxx::LogString &level, const char *format, ... )
{
	if (NULL == logger) return;
	
	LevelPtr pLevel = Level::toLevel(level);
	
	char message[_MSGBUF_MAX];
	va_list ArgList;
	va_start(ArgList, format);
	vsnprintf(message, sizeof(message), format, ArgList);
	va_end(ArgList);
	helpers::MessageBuffer oss_;
	logger->forcedLog(pLevel, oss_.str(oss_ << message), LOG4CXX_LOCATION);
}

void aLogger::assertlog(bool condition, const log4cxx::LogString &level, const char *format, ... )
{
	if (NULL == logger || !condition) return;
	
	LevelPtr pLevel = Level::toLevel(level);
	
	char message[_MSGBUF_MAX];
	va_list ArgList;
	va_start(ArgList, format);
	vsnprintf(message, sizeof(message), format, ArgList);
	va_end(ArgList);
	helpers::MessageBuffer oss_;
	logger->forcedLog(pLevel, oss_.str(oss_ << message), LOG4CXX_LOCATION);
}


四、测试程序

#include <unistd.h>
#include <map>
#include <cstdlib>
#include <memory>
#include "aLogger.h"

using namespace std;

map<string, string> argMap;

int main(int argc, char *argv[])
{
	int result = 0;
	opterr = 0;
	while ((result = getopt(argc, argv, "dl:")) != -1)
	{
		switch(result)
		{
			case ‘d‘:
			{
				argMap["daemon"] = "1";
				break;	
			}
			case ‘l‘:
			{
				argMap["logPath"] = optarg;
				break;
			}
		}
	}
	auto_ptr<aLogger> logger(new aLogger("logicserver"));
	logger->setLevel("TRACE");
	if (atoi(argMap["daemon"].c_str()) == 1)
	{
		logger->removeConsoleLog();
		daemon(1, 1);
	}
	while (true)
        {
                logger->debug("定时测试, 字符串%s, 数字%d", "test", 123456789);
		logger->assertlog(1 == 1, "ERROR", "条件测试, 条件满足则输出 字符串%s", "test");
                sleep(1);
        }
	return 0;
}

说明:

a) daemon函数让程序后台运行

int daemon(int nochdir, int noclose);

参数:

当 nochdir为零时,当前目录变为根目录,否则不变;

当 noclose为零时,标准输入、标准输出和错误输出重导向为/dev/null,也就是不输出任何信 息,否则照样输出。

返回值:

deamon()调用了fork(),如果fork成功,那么父进程就调用_exit(2)退出,所以看到的错误信息 全部是子进程产生的。如果成功函数返回0,否则返回-1并设置errno。


五、搭建编译环境

相关资讯

发表评论
网友评论0 条评论)
暂无评论