大きな C++ プロジェクトで log4cxx を使用していますが、ログ記録時に log4cxx が複数の変数を処理する方法が本当に好きではありません。
LOG4CXX_DEBUG(logger, "test " << var1 << " and " << var3 " and .....)
可変長引数のように printf を使用することを好みます。
LOG4CXX_DEBUG(logger, "%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