我使用log4cxx在一个大的C++项目,但我真的不喜欢log4cxx登录时如何处理多个变量:可变长度参数
LOG4CXX_DEBUG(记录器,“测试” < < VAR1 < < “和” < < VAR3“和.....)
我更喜欢使用的printf像可变长度参数:
LOG4CXX_DEBUG(记录器, ”测试%d和%d“,VAR1,VAR3)
所以我实现了这个小包装上log4cxx
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <log4cxx/logger.h>
#include "log4cxx/basicconfigurator.h"
const char * log_format(const char *fmt, ...);
#define MYLOG_TRACE(logger, fmt, ...) LOG4CXX_TRACE(logger, log_format(fmt, ## __VA_ARGS__))
#define MYLOG_DEBUG(logger, fmt, ...) LOG4CXX_DEBUG(logger, log_format(fmt, ## __VA_ARGS__))
#define MYLOG_INFO(logger, fmt, ...) LOG4CXX_INFO(logger, log_format(fmt, ## __VA_ARGS__))
#define MYLOG_WARN(logger, fmt, ...) LOG4CXX_WARN(logger, log_format(fmt, ## __VA_ARGS__))
#define MYLOG_ERROR(logger, fmt, ...) LOG4CXX_ERROR(logger, log_format(fmt, ## __VA_ARGS__))
#define MYLOG_FATAL(logger, fmt, ...) LOG4CXX_FATAL(logger, log_format(fmt, ## __VA_ARGS__))
static log4cxx::LoggerPtr logger(log4cxx::Logger::getRootLogger());
int main(int argc, char **argv)
{
log4cxx::BasicConfigurator::configure();
MYLOG_INFO(logger, "Start ");
MYLOG_WARN(logger, "In running this in %d threads safe?", 1000);
MYLOG_INFO(logger, "End ");
return 0;
}
const char *log_format(const char *fmt, ...)
{
va_list va;
static char formatted[1024];
va_start(va, fmt);
vsnprintf(formatted, 1024, fmt, va);
va_end(va);
return formatted;
}
的顶部,这个完美的作品,但我知道使用的是静态变量(格式化)如果我开始使用线程可以成为问题,并且每个线程记录到同一个地方。
我不是log4cxx的专家,所以我想知道如果LOG4CXX宏自动处理并发线程访问?或者我必须在log_format方法周围实现某种锁定?由于性能影响,我不想避免这种情况。
要编译和测试这个程序(在Ubuntu)使用:即log4cxx确实是线程安全的
g++ -o loggertest loggertest.cpp -llog4cxx
谢谢。发现这个话题相当有用。我同意使用std :: string的意见,甚至认为它可能会对性能产生更大的影响。猜测主要的原因是在这种情况下逻辑变得更清洁。 – vitrums 2013-11-25 21:59:56