2010-06-03 2 views
2

J'utilise log4cxx dans un grand projet C++, mais je n'aime vraiment pas comment gère log4cxx plusieurs variables lors de la connexion:arguments de longueur variable dans les macros log4cxx de LOG4CXX_

LOG4CXX_DEBUG (enregistreur, "test" < < var1 < < "et" < < var3 "et .....)

Je préfère utiliser printf comme arguments de longueur variable:

LOG4CXX_DEBUG (enregistreur, "test% d et% d", var1, var3)

Je mis en œuvre cette petite enveloppe au-dessus de 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;                                           
} 

Et cela fonctionne parfaitement, mais je sais en utilisant cette variable statique (formaté) peut devenir problématique si je commence à l'aide de fils et chaque enregistrement de fil au même endroit .

Je ne suis pas expert en log4cxx donc je me demandais si les macros log4cxx gèrent l'accès thread concurrent automatiquement? ou dois-je implémenter une sorte de verrouillage autour de la méthode log_format? quelque chose que je ne voulais pas éviter en raison des conséquences sur les performances.

Pour compiler et tester ce programme (dans Ubuntu) utiliser:

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

Merci. Trouvé ce sujet plutôt utile. Je suis d'accord avec les commentaires pour utiliser std :: string à la place, même si cela pourrait avoir un plus grand impact sur les performances. Supposons que le facteur majeur est que la logique devient plus propre dans ce cas. – vitrums

Répondre

0

Ces différentes macros sont des macros standard C. Je ne vois rien là-dedans qui leur permettrait de protéger une fonction que vous définissez à partir de ses propres données statiques. Les macros utilisent C++ donc vous devriez pouvoir retourner une chaîne std :: à partir de votre fonction log_format et ainsi éviter le problème.

Questions connexes