2012-01-09 60 views
5

我想登錄到我的代碼中的不同文件。用log4cxx登錄到不同的文件

我該怎麼做,在Log4cxx使用XML配置或編程代碼...

  • 假設我有1.K,K + 1,...,n個分量。
  • 他們在同一個應用程序中運行
  • 我想分量k的日誌記錄器,K,K + 1個組件日誌記錄-K + 1 同時

更新:

Logger.addAppender()方法:

log4cxx::helpers::Pool p; 

std::string paramAppender = "appxNormalAppender"; 
std::string paramFileName = "\\Logs\\MyLog.txt"; 

LOG4CXX_DECODE_CHAR(logAppender, paramAppender); 
LOG4CXX_DECODE_CHAR(logFileName, paramFileName); 


FileAppenderPtr fileAppender = 
logger->getLoggerRepository()->getRootLogger()->getAppender(logAppender); 

if(fileAppender!= NULL) 
{ 


    fileAppender->setFile(logFileName); 

    fileAppender->activateOptions(p); 

} 

這不起作用,因爲

假設我爲k分量設置FileName爲Logger-k,它將記錄到 Logger-k,然後我爲文件k + 1設置文件名爲Logger-k + 1,則組件k, 和k + 1記錄相同的loggerk + 1文件。看來最後一個文件名替代或影響其他所有...

而且

所有compoenent compenent 1,... compoeent K,componentk + 1,... 組件n在相同的應用程序...

回答

2

正常創建每個記錄器,然後爲每個記錄器通過Logger.addAppender()方法添加一個FileAppender集合到所需的文件。

+0

它不工作...我把我的問題的更新...可能是我做錯了什麼...所以我把一些代碼... – Novalis 2012-01-09 15:07:41

+0

你正試圖重置根級別記錄器的文件名稱,因此在一切日誌。您需要爲每個組件添加一個單獨的FileAppender以登錄到指定的文件。 – diverscuba23 2012-01-09 16:11:20

+0

可以給一個示例代碼...如何獲得單獨的FileAppender? – Novalis 2012-01-09 16:31:21

1

您確實需要爲您的記錄器創建單獨的appender。在我的示例中,我創建了afile1afile2 appenders。我還創建了兩個記錄器:my.logger1my.logger2。當您使用my.logger1它記錄到mylog1文件,當您使用my.logger2它記錄到mylog2文件。

這裏是我的log.properties文件:

log4cplus.appender.afile1.layout=log4cplus::PatternLayout 
log4cplus.appender.afile1.layout.ConversionPattern=%d [ %c{1} ] [ %-5p ] %m%n 
log4cplus.appender.afile1=log4cplus::RollingFileAppender 
log4cplus.appender.afile1.File=mylog1.log 
log4cplus.appender.afile1.MaxFileSize=5MB 
log4cplus.appender.afile1.MaxBackupIndex=2 

log4cplus.appender.afile2.layout=log4cplus::PatternLayout 
log4cplus.appender.afile2.layout.ConversionPattern=%d [ %c{1} ] [ %-5p ] %m%n 
log4cplus.appender.afile2=log4cplus::RollingFileAppender 
log4cplus.appender.afile2.File=mylog2.log 
log4cplus.appender.afile2.MaxFileSize=5MB 
log4cplus.appender.afile2.MaxBackupIndex=2 

log4cplus.logger.my.logger1=INHERIT, afile1 
log4cplus.additivity.my.logger1=false 
log4cplus.logger.my.logger2=INHERIT, afile2 
log4cplus.additivity.my.logger2=false 

下面是一個例子PROGRAMM:
example.cpp:

#include <iostream> 
#include <log4cplus/logger.h> 
#include <log4cplus/loglevel.h> 
#include <log4cplus/configurator.h> 
#include <log4cplus/fileappender.h> 

#define MYLOG1_INFO(logEvent) LOG4CPLUS_INFO (log4cplus::Logger::getInstance("my.logger1"), logEvent) 
#define MYLOG2_INFO(logEvent) LOG4CPLUS_INFO (log4cplus::Logger::getInstance("my.logger2"), logEvent) 

int main(int argc, char**argv) 
{ 
    try 
    { 
     log4cplus::PropertyConfigurator::doConfigure("log.properties"); 
    } 
    catch(...) 
    { 
    std::cerr<<"Exception occured while opening log.properties\n"; 
    return -1; 
    } 
    MYLOG1_INFO("hello world!"); 
    MYLOG2_INFO("hello world!"); 
    return 0; 
} 

下面是Makefile文件(我想我的log4cplus是建在父母的dirrectory):

CXXFLAGS+=-I$(abspath ../log4cplus-1.0.4/include) 
all: example.o 
    $(CXX) $^ $(abspath ../log4cplus-1.0.4/src/.libs/liblog4cplus.a) -lpthread -o test 

試試這個例子,你應該知道appender是如何工作的

Log4cplus大多是像log4j。所以你可以閱讀log4j的基本原理。 並獲得您需要訪問的類名稱log4cplus.sourceforge.net

關於日誌格式。 log4cplus的文檔僅在doxygen中可用。所以在這裏你可以看到formating in pattern layout
如果你想登錄進程id,比你應該在你的佈局轉換模式中使用%I
例如:

... 
log4cplus.appender.afile2.layout.ConversionPattern=[%i] %m%n 
... 

它將記錄進程ID和消息

+0

對不起,寫了關於log4cplus。但相信我,它比log4cxx更好 – 2r2w 2012-02-14 17:46:08

+0

看來,log4cplus是「死」。[2011年1月最後一個版本],它也缺乏文檔。我可以選擇log4cplus,如果我可以這樣做:檢查我的問題:http://stackoverflow.com/questions/9082413/add-process-id-to-log-file-name-in-log4cxx – Novalis 2012-02-15 07:47:58

+0

最新版本的log4cxx是在2008-04-03 http://logging.apache.org/log4cxx/changes-report.html 和最新的釋放log4cplus是在2011年。 更多log4cxx有0.10版本和log4cplus有版本1.04 所以它看起來像log4cxx是更死的項目 – 2r2w 2012-02-15 07:51:42

1

對於動態組件試試這個:

#include <boost/foreach.hpp> 
#include <boost/thread.hpp> 
#include <boost/bind.hpp> 
#include <boost/lexical_cast.hpp> 

#include <log4cxx/Logger.h> 
#include <log4cxx/LogManager.h> 
#include <log4cxx/xml/domconfigurator.h> 
#include <log4cxx/FileAppender.h> 
#include <log4cxx/SimpleLayout.h> 
#include <log4cxx/helpers/transcoder.h> 


void func(int k) { 
    std::string strName = "Log." + boost::lexical_cast<std::string>(k); 
    log4cxx::LoggerPtr log = log4cxx::Logger::getLogger(strName); 
    LOG4CXX_DECODE_CHAR(fileName, strName + ".log"); 
    log4cxx::FileAppenderPtr appender(new log4cxx::FileAppender(new log4cxx::SimpleLayout, fileName, false)); 
    log->addAppender(appender); 

    LOG4CXX_INFO(log, strName); 

    log->removeAppender(appender); 
} 

int main(int argc, char * argv[]) { 
    log4cxx::xml::DOMConfigurator::configure("trace.xml"); 
    if(log4cxx::Logger::getLogger("Log")->getAllAppenders().empty()) { 
     std::cout << "failed to config log4cxx" << std::endl; 
     return 1; 
    } 
    log4cxx::LoggerPtr log = log4cxx::Logger::getLogger("Log"); 

    boost::thread_group threadGroup; 
    for(int k = 0; k != 3; ++k) { 
     threadGroup.create_thread(boost::bind(func, k)); 
    } 
    threadGroup.join_all(); 
    return 0; 
} 

簡單trace.xml

<?xml version="1.0" encoding="UTF-8" ?> 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> 
    <appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender"> 
     <param name="Target" value="System.out"/> 
     <layout class="org.apache.log4j.SimpleLayout"/> 
    </appender> 

    <root> 
     <level value="all"/> 
    </root> 

    <category name="Log"> 
     <level value="INFO"/> 
     <appender-ref ref="ConsoleAppender"/> 
    </category> 
</log4j:configuration>