2010-06-03 112 views
2

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

谢谢。发现这个话题相当有用。我同意使用std :: string的意见,甚至认为它可能会对性能产生更大的影响。猜测主要的原因是在这种情况下逻辑变得更清洁。 – vitrums 2013-11-25 21:59:56

回答

0

这些方便的宏是标准的C宏。 我可以看到没有任何东西可以让他们保护一个你从定义自己的静态数据中定义的函数。

宏使用C++,所以你应该能够从你的log_format函数返回一个std :: string,从而避免这个问题。