一、配置文件
log.conf:
#a simple test config
log4cpp.rootCategory=DEBUG, rootAppender
#print to File
#log4cpp.appender.rootAppender=RollingFileAppender
#log4cpp.appender.rootAppender.fileName=rootAppender.log #path is ok ! eg: /usr/local/rootAppender.log
#log4cpp.appender.rootAppender.maxFileSize=1024*1024 # 200 bytes, 1M=1024*1024
#log4cpp.appender.rootAppender.maxBackupIndex=2 #file numbers
#log4cpp.appender.rootAppender.layout=PatternLayout
#log4cpp.appender.rootAppender.layout.ConversionPattern=%d [%p] %m%n
#print to Console
log4cpp.appender.rootAppender=ConsoleAppender
log4cpp.appender.rootAppender.layout=PatternLayout
log4cpp.appender.rootAppender.layout.ConversionPattern=%d [%p] - %m%n
二、代码
logger.h:
#ifndef _LOGGER_H
#define _LOGGER_H
#include <string>
using namespace std;
#ifdef USE_LOG4CPP
#include "log4cpp/Category.hh"
#include "log4cpp/CategoryStream.hh"
#include "log4cpp/PropertyConfigurator.hh"
using namespace log4cpp;
#elif defined USE_LOG4CXX
#include <log4cxx/logger.h>
#include <log4cxx/propertyconfigurator.h>
using namespace log4cxx;
#endif
#define LoggerName "MyApp"
#define AppenderName "rootAppender"
//使用的时候,通过定义不同的宏来使用不同的库,例如使用log4cpp,编译的时候,
//使用-DUSE_LOG4CPP宏,并在链接的时候,使用-llog4cpp进行库链接;同理使用log4cxx
//LOG4CPP_INFO_S 时log4cpp为了方便封装定义的宏
#ifdef USE_LOG4CPP
extern log4cpp::Category *logger_;
#define LOG_DEBUG(msg) \
LOG4CPP_DEBUG_S((*logger_))<<msg<<"("<<__FILE__<<":"<<__LINE__<<")";
#define LOG_INFO(msg) \
LOG4CPP_INFO_S((*logger_))<<msg<<"("<<__FILE__<<":"<<__LINE__<<")";
#define LOG_WARN(msg) \
LOG4CPP_WARN_S((*logger_))<<msg<<"("<<__FILE__<<":"<<__LINE__<<")";
#define LOG_ERROR(msg) \
LOG4CPP_ERROR_S((*logger_))<<msg<<"("<<__FILE__<<":"<<__LINE__<<")";
#define LOG_FATAL(msg) \
LOG4CPP_FATAL_S((*logger_))<<msg<<"("<<__FILE__<<":"<<__LINE__<<")";
#elif defined USE_LOG4CXX
extern LoggerPtr logger_;
#define LOG_DEBUG(msg) \
{\
stringstream temp_; \
temp_<<msg<<"("<<__FILE__<<":"<<__LINE__<<")"; \
LOG4CXX_DEBUG(logger_, temp_.str()); \
}
#define LOG_INFO(msg) \
{\
stringstream temp_; \
temp_<<msg<<"("<<__FILE__<<":"<<__LINE__<<")"; \
LOG4CXX_INFO(logger_, temp_.str()); \
}
#define LOG_WARN(msg) \
{\
stringstream temp_; \
temp_<<msg<<"("<<__FILE__<<":"<<__LINE__<<")"; \
LOG4CXX_WARN(logger_, temp_.str()); \
}
#define LOG_ERROR(msg) \
{\
stringstream temp_; \
temp_<<msg<<"("<<__FILE__<<":"<<__LINE__<<")"; \
LOG4CXX_ERROR(logger_, temp_.str()); \
}
#define LOG_FATAL(msg) \
{\
stringstream temp_; \
temp_<<msg<<"("<<__FILE__<<":"<<__LINE__<<")"; \
LOG4CXX_FATAL(logger_, temp_.str()); \
}
#endif
void InitLog(const char *conf_file);
string mformat(const char *fmt, ...);
#endif /*_LOGGER_H*/
logger.cpp:
#include "logger.h"
#ifdef USE_LOG4CPP
log4cpp::Category *logger_;
#elif defined USE_LOG4CXX
LoggerPtr logger_(Logger::getLogger(LoggerName));
#endif
void InitLog(const char *conf_file)
{
#ifdef USE_LOG4CPP
log4cpp::PropertyConfigurator::configure(conf_file);
log4cpp::Category& log = log4cpp::Category::getInstance(string(AppenderName));
logger_ = &log;
#elif defined USE_LOG4CXX
PropertyConfigurator::configure(File(conf_file)); // Configure file, log4j format
logger_ = Logger::getLogger("org.apache.log4j.RollingFileAppender"); // Appender name
#endif
}
string mformat(const char *fmt, ...)
{
size_t size = 1024;
char* buf = new char[size];
while(1)
{
va_list args;
int n;
va_start(args, fmt);
n = vsprintf(buf, fmt, args);
va_end(args);
if ((n > -1) && (static_cast<size_t>(n) < size))
{
std::string s(buf);
delete [] buf;
return s;
}
// Else try again with more space.
size = (n > -1) ?
n + 1 : // ISO/IEC 9899:1999
size * 2; // twice the old size
delete [] buf;
buf = new char[size];
}
}
main.cpp:
#include <iostream>
using namespace std;
#include "logger.h"
int main()
{
InitLog("log.conf");
LOG_DEBUG("debug");
LOG_INFO("info");
return 0;
}
三、编译
3.1 Windows编译
属性 -> 配置属性 -> C/C++ -> 预处理器 -> 预处理器定义 加入宏:USE_LOG4CPP。
3.2 Linux编译
Makefile编译时加入宏:USE_LOG4CPP。
四、输出
在当前控制台下,输出日志:
2013-12-13 16:19:25,431 [DEBUG] - debug(fast_dr302.cpp:12)
2013-12-13 16:19:25,431 [INFO] - info(fast_dr302.cpp:13)
修改配置文件log.conf,可将该日志输出到rootAppender.log文件中。