Как напечатать имя метода в файле журнала, используя log4cplus

Я написал библиотеку оболочки на log4cplus. Моя библиотека имеет LogMessage функция, внутри которой я вызываю библиотечную функцию 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;

ОБНОВИТЬ:
Извините, я забыл упомянуть, что у меня есть #define функция LogMessage с PrintLogMessage

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

Так что в приложении я использую мне нужно написать только эту строку

application.cpp

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

И я хочу написать похожий вид

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

за __FUNCTION__ функциональность. Я не хочу, чтобы пользователь писал ФАЙЛ, ЛИНИЯ, ФУНКЦИЯ каждый раз.

1

Решение

Используйте эту функцию из Logger класс вместо:

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

Подготовить InternalLoggingEvent экземпляр заранее. использование InternalLoggingEvent::setFunction() установить информацию о функции в экземпляре события.

Я перечитал ваш вопрос и код, я думаю, вы не используете log4cplus так, как это было задумано.

Во-первых, ваш LogMessage не следует создавать дополнения или присоединять дополнения к регистраторам каждый раз, когда он вызывается. Appenders и loggers должны быть настроены в начале вашего приложения.

Взглянуть 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);
}

Эта функция внутренне используется различными LOG4CPLUS_*() макросы в loggingmacros.h, Он показывает вам, как заполнить InternalLoggingEvent экземпляр и как заставить его журнал. Используйте это как пример для собственного LogMessage() функция.

Вам придется заменить forcedLog() с log() чтобы он проверил порог Logger.

Одна реализация может выглядеть так:

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())
2

Другие решения

Если вы не можете изменить LogMessage Функция, которую вы могли бы использовать этот метод:

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

Поскольку запятая отсутствует, компилятор объединит вывод __FUNCTION__ и ваше сообщение.

РЕДАКТИРОВАТЬ:

#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

По вопросам рекламы [email protected]