2

我在一个大型 C++ 项目中使用 log4cxx,但我真的不喜欢 log4cxx 在记录时如何处理多个变量:

LOG4CXX_DEBUG(logger, "test" << var1 << " and " << var3 " and .....)

我更喜欢使用 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 中),请使用:

g++ -o loggertest loggertest.cpp  -llog4cxx
4

2 回答 2

0

该线程声明 log4cxx 确实是线程安全的。

http://old.nabble.com/thread-safe-log4cxx-td17721835.html

可能想测试只是为了确保......

于 2010-06-03T03:26:15.637 回答
0

这些便利宏是标准的 C 宏。我看不到任何东西可以使它们保护您定义的函数不破坏其自己的静态数据。

宏确实使用 C++,因此您应该能够从 log_format 函数返回一个 std::string ,从而避免该问题。

于 2013-09-18T11:35:16.037 回答