Reputation: 1428
I have written a wrapper library on log4cplus. My library has LogMessage
function inside which i am calling log4cplus library function to store the log message.
eg. 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;
}
Now from my application i want to pass function name also.
eg. application.cpp
int main()
{
LogMessage(DEBUG_LEVEL, __FILE__, __LINE__, __FUNCTION__, "This is main function");
return 0;
}
How should i print this log message to the console screen? This below function only takes file and line number as an argument. And i want to print function name as well.
void log(LogLevel ll, const log4cplus::tstring& message,
const char* file=NULL, int line=-1) const;
UPDATE: Sorry i forgot to mention i have #define my LogMessage function with PrintLogMessage
#define PrintLogMessage(dwLogLevel, lpszLogMessage) \
LogMessage(dwLogLevel, _FILE, __LINE__, lpszLogMessage)
So in application i am using i need to write only this line
application.cpp
int main()
{
PrintLogMessage(DEBUG_LEVEL, "This is main function");
return 0;
}
And i want to write similar kind of
#define PrintLogMessage(dwLogLevel, lpszLogMessage) \
LogMessage(dwLogLevel, _FILE, __LINE__, __FUNCTION__, lpszLogMessage)
for __FUNCTION__
functionality. I dont want user to write FILE, LINE, FUNCTION everytime.
Upvotes: 1
Views: 2776
Reputation: 18238
Use this function from the Logger
class instead:
void log (spi::InternalLoggingEvent const &) const;
Prepare the InternalLoggingEvent
instance in advance. Use InternalLoggingEvent::setFunction()
to set the function information on the event instance.
I have re-read your question and the code I think your are not using log4cplus the way it is intended.
First off, your LogMessage
should not be creating appenders or attaching appenders to loggers each time it is invoked. Appenders and loggers should be set up at the start of your application.
Take a look loggingmacros.h
and the macros there. You can avoid having to define your own macros or functions if you use the LOG4CPLUS_ERROR
, LOG4CPLUS_INFO
, etc. macros. See the tests/
directory for some examples of how to use these macros.
If you want to still avoid using the log4cplus provided macros, take a look at the source in 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);
}
This function is internally used by the various LOG4CPLUS_*()
macros in loggingmacros.h
. It shows you how to fill the InternalLoggingEvent
instance and how to force its log. Use it as an example for your own LogMessage()
function.
You would have to replace forcedLog()
with log()
to have it check the Logger threshold.
One implementation could look like this:
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())
Upvotes: 2
Reputation: 1490
If you can't modify the LogMessage function you could use this method:
int main()
{
LogMessage(DEBUG_LEVEL, __FILE__, __LINE__, "This is "__FUNCTION__" function");
// notice the missing commas ------------------------^------------^
}
Since there is no comma the compiler will concatenate the output of __FUNCTION__ and your message.
EDIT:
#define PrintLogMessage(dwLogLevel, lpszLogMessage) \
LogMessage(dwLogLevel, _FILE, __LINE__, __FUNCTION__ lpszLogMessage)
or
#define PrintLogMessage(dwLogLevel, lpszLogMessage) \
LogMessage(dwLogLevel, _FILE, __LINE__, lpszLogMessage __FUNCTION__)
or
#define PrintLogMessage(dwLogLevel, lpszLogMessage) \
LogMessage(dwLogLevel, _FILE, __LINE__, lpszLogMessage __FUNCTION__ "function")
or
#define PrintLogMessage(dwLogLevel, lpszLogMessage) \
LogMessage(dwLogLevel, _FILE, __LINE__, std::string(lpszLogMessage) + std::string(__FUNCTION__))
Upvotes: 0