一、配置文件
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文件中。