2013-08-30 3 views
1

log4cplus에 래퍼 라이브러리를 작성했습니다. 내 라이브러리 LogMessage 함수 안에 로그 메시지를 저장하는 log4cplus 라이브러리 함수를 호출합니다.log4cplus를 사용하여 로그 파일에 메서드 이름을 인쇄하는 방법

예 : application.cpp

int main() 
{ 
LogMessage(DEBUG_LEVEL, __FILE__, __LINE__, "This is main function"); 
return 0; 
} 

mylibrary.cpp는

HRESULT 
LogMessage(
__in DWORD dwLogLevel, 
__in LPSTR lpszFileName, 
__in DWORD dwLineNumber, 
__in LPSTR lpszLogMessage 
) 
{ 
     // 
     // Instantiating a console appender 
     // 
     SharedAppenderPtr _ConsoleAppender(new ConsoleAppender()); 
     _ConsoleAppender->setName(LOG4CPLUS_TEXT("AppenderName")); 

     // 
     // Creating a pattern to display log events 
     // 
     log4cplus::tstring pattern = LOG4CPLUS_TEXT("%L %F %r %d{%m/%d/%y %H:%M:%S} %-5p %c - %m%n"); 

     // 
     // Instantiating a layout object with PatternLayout 
     // 
     _Layout = std::auto_ptr<Layout>(new log4cplus::PatternLayout(pattern)); 

     // 
     // Attaching the layout object to the appender object 
     // 
     _ConsoleAppender->setLayout(_Layout); 

     // 
     // Getting root logger and adding the Console Appender with root 
     // logger 
     // 
     Logger::getRoot().addAppender(_ConsoleAppender); 
     Logger::getRoot().setAdditivity(FALSE); 

     // 
     // Instantiating a logger 
     // 
     Logger _Logger = Logger::getInstance(LOG4CPLUS_TEXT("_Logger")); 
     _Logger.addAppender(_ConsoleAppender); 
     _Logger.setAdditivity(FALSE); 

     // 
     // Printing the log messages on the console 
     // 
     switch(dwLogLevel) 
     { 
     case DEBUG_LEVEL: 
      { 
       _Logger.log(DEBUG_LOG_LEVEL, lpszLogMessage, lpszFileName, dwLineNumber); 
       break; 
      } // DEBUG_LEVEL 
     case INFO_LEVEL: 
      { 
       _Logger.log(INFO_LOG_LEVEL, lpszLogMessage, lpszFileName, dwLineNumber); 
       break; 
      } // INFO_LEVEL 
     case WARN_LEVEL: 
      { 
       _Logger.log(WARN_LOG_LEVEL, lpszLogMessage, lpszFileName, dwLineNumber); 
       break; 
      } // WARN_LEVEL 
     case ERROR_LEVEL: 
      { 
       _Logger.log(ERROR_LOG_LEVEL, lpszLogMessage, lpszFileName, dwLineNumber); 
       break; 
      } // ERROR_LEVEL 
     case FATAL_LEVEL: 
      { 
       _Logger.log(FATAL_LOG_LEVEL, lpszLogMessage, lpszFileName, dwLineNumber); 
       break; 
      } // 
     default: 
      { 
       HRESULT_FROM_WIN32(ERROR_INVALID_DATA); 
       break; 
      } // default 
     } // switch 

return hResult; 
} 

지금 내 응용 프로그램에서 나는 또한 함수 이름을 전달하려는.

예 : application.cpp는

int main() 
    { 
    LogMessage(DEBUG_LEVEL, __FILE__, __LINE__, __FUNCTION__, "This is main function"); 
    return 0; 
    } 

어떻게 콘솔 화면이 로그 메시지를 인쇄해야합니까? 이 함수는 파일과 행 번호 만 인수로 취합니다. 그리고 난뿐만 아니라 함수 이름을 인쇄 싶습니다.

void log(LogLevel ll, const log4cplus::tstring& message, 
       const char* file=NULL, int line=-1) const; 

UPDATE : 난 내가 만이 줄을 쓸 필요가 사용하고 PrintLogMessage

응용 프로그램에서 그래서
#define PrintLogMessage(dwLogLevel, lpszLogMessage) \ 
           LogMessage(dwLogLevel, _FILE, __LINE__, lpszLogMessage) 

와 #DEFINE 내 LogMessage 기능이 언급하는 것을 잊었다 죄송합니다

application.cpp

int main() 
{ 
    PrintLogMessage(DEBUG_LEVEL, "This is main function"); 
return 0; 
} 

와 나는 __FUNCTION__ 기능을

#define PrintLogMessage(dwLogLevel, lpszLogMessage) \ 
            LogMessage(dwLogLevel, _FILE, __LINE__, __FUNCTION__, lpszLogMessage) 

의 유사한 종류를 쓰고 싶어요. 사용자가 FILE, LINE, FUNCTION을 작성하고 싶지 않습니다.

답변

2

대신 Logger 클래스에서이 기능을 사용

void log (spi::InternalLoggingEvent const &) const; 

사전에 InternalLoggingEvent 인스턴스를 준비합니다. InternalLoggingEvent::setFunction()을 사용하여 이벤트 인스턴스에 대한 기능 정보를 설정하십시오.

UPDATE

I이 다시 읽고 질문하고 난 당신이 의도하는 방식을 log4cplus 사용하지 않을 생각하는 코드입니다.

먼저, LogMessage은 호출 할 때마다 로더에 어 펜더를 만들거나 첨부 파일을 첨부해서는 안됩니다. appenders와 로거는 신청서를 시작할 때 설정되어야합니다.

loggingmacros.h과 그 매크로를보세요. LOG4CPLUS_ERROR, LOG4CPLUS_INFO 등의 매크로를 사용하면 자신의 매크로 또는 함수를 정의하지 않아도됩니다. 이 매크로를 사용하는 방법에 대한 예제는 tests/ 디렉토리를 참조하십시오. 여전히 log4cplus 제공하는 매크로를 사용하지 않도록하려면

loggingmacros.cxx에서 소스를 살펴 :

void 
macro_forced_log (log4cplus::Logger const & logger, 
    log4cplus::LogLevel log_level, log4cplus::tstring const & msg, 
    char const * filename, int line, char const * func) 
{ 
    log4cplus::spi::InternalLoggingEvent & ev = internal::get_ptd()->forced_log_ev; 
    ev.setLoggingEvent (logger.getName(), log_level, msg, filename, line); 
    ev.setFunction (func ? func : ""); 
    logger.forcedLog (ev); 
} 

이 기능은 내부적으로 loggingmacros.h의 다양한 LOG4CPLUS_*() 매크로에 의해 사용된다. InternalLoggingEvent 인스턴스를 채우는 방법과 로그를 강제로 수행하는 방법을 보여줍니다. 자신의 LogMessage() 함수의 예제로 사용하십시오.

로거 임계 값을 확인하려면 forcedLog()log()으로 대체해야합니다.

하나의 구현은 다음과 같을 수 있습니다 : 회신에 대한

HRESULT 
LogMessage(
    __in DWORD dwLogLevel, 
    __in LPCSTR lpszFileName, 
    __in DWORD dwLineNumber, 
    __in LPCSTR lpszLogMessage, 
    __in LPCSTR lpszFunction) 
{ 
    log4cplus::spi::InternalLoggingEvent ev; 
    log4cplus::Logger logger (Logger::getRoot()); 
    ev.setLoggingEvent (logger.getName(), dwLogLevel, lpszLogMessage, lpszFileName, 
     dwLineNumber); 
    ev.setFunction (func ? lpszFunction : ""); 
    logger.forcedLog (ev); // or logger.log(ev) 

    return S_OK; 
} 

#define PrintLogMessage(ll, msg) \ 
    LogMessage(ll, __FILE__, __LINE__, msg, LOG4CPLUS_MACRO_FUNCTION()) 
+0

답장을 보내 주셔서 감사합니다. _Logger를 인스턴스화 한 후이 코드를 추가했습니다. 'spi :: InternalLoggingEvent * ent = new InternalLoggingEvent(); ent-> setLoggingEvent (LOG4CPLUS_TEXT ("_ Logger"), dwLogLevel, lpszLogMessage, lpszFileName, dwLineNumber); ent-> setFunction (lpszFunctionName); ' – Ankit

+0

그리고 switch case 문에서'mqLogger.log (* ent);'를 사용하고 있습니다. 그러나 그것은 콘솔 화면에 전혀 인쇄되지 않습니다. 내가 잘못하고있는 곳을 말해 줄 수 있니? spi :: InternalLoggingEvent 클래스의 ent 개체에서 모든 값을 가져옵니다. – Ankit

+0

저는 올바른 방법으로'InternalLoggingEvent' 인스턴스를 생성하지 않을 것이라고 생각합니다. – Ankit

0

당신이이 방법을 사용할 수있는 LogMessage 기능을 수정할 수없는 경우 컴파일러는 __FUNCTION__ 및 메시지의 출력을 연결합니다에는 쉼표가 없기 때문에

int main() 
{ 
    LogMessage(DEBUG_LEVEL, __FILE__, __LINE__, "This is "__FUNCTION__" function"); 
    // notice the missing commas ------------------------^------------^ 
} 

합니다.

EDIT :

#define PrintLogMessage(dwLogLevel, lpszLogMessage) \ 
LogMessage(dwLogLevel, _FILE, __LINE__, __FUNCTION__ lpszLogMessage) 

또는

#define PrintLogMessage(dwLogLevel, lpszLogMessage) \ 
LogMessage(dwLogLevel, _FILE, __LINE__, lpszLogMessage __FUNCTION__) 

또는

#define PrintLogMessage(dwLogLevel, lpszLogMessage) \ 
LogMessage(dwLogLevel, _FILE, __LINE__, lpszLogMessage __FUNCTION__ "function") 

또는

#define PrintLogMessage(dwLogLevel, lpszLogMessage) \ 
LogMessage(dwLogLevel, _FILE, __LINE__, std::string(lpszLogMessage) + std::string(__FUNCTION__)) 
,
+0

감사합니다. 업데이트 된 질문을 확인하십시오. – Ankit

+0

업데이트 된 답변 확인 – user1233963

+0

PrintLogMessage (dwLogLevel, lpszLogMessage); 이 오류'말하는 : #DEFINE LogMessage \ PrintLogMessage (dwLogLevel, lpszLogMessage) (dwLogLevel, _file, __LINE__, __FUNCTION__ lpszLogMessage) 예상이 ')'' – Ankit