我使用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