开发者

Variable length arguments in log4cxx LOG4CXX_ macros

开发者 https://www.devze.com 2023-01-02 06:37 出处:网络
I am using log4cxx in a big C++ project but I really don\'t like how log4cxx handles multiple variables when logging:

I am using log4cxx in a big C++ project but I really don't like how log4cxx handles multiple variables when logging:

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

I prefer using printf like variable length arguments:

LOG4CXX_DEBUG(logger, "test %d and %d", var1, var3)

So I implemented this small wrapper on top of 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;                                                                                                                                                                          
}

And this works perfectly but I know using that static variable (formatted) can become problematic if I start using threads and each thread logging to the same place.

I am no expert in log4cxx so I was wondering if the LOG4CXX macros are handling concurrent thread access automatically? or do I have to implement some sort of locking around the log_format method? something that I wan't to avoid due to performance implications.

To compile and test this program (in Ubuntu) use :

g++ -o loggertest loggertest.cpp  -llog4cxx


Those convenience macros are standard C macros. I can see nothing in there that would make them protect a function you define from clobbering its own static data.

The macros do use C++ so you should be able to return a std::string from your log_format function and thus avoid the problem.


This thread states that log4cxx is indeed thread safe.

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

May want to test just to make sure though...

0

精彩评论

暂无评论...
验证码 换一张
取 消