1

我在 log4cplus 上写了一个包装库。我的库有LogMessage一个函数,我在其中调用 log4cplus 库函数来存储日志消息。

例如。应用程序.cpp

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

图书馆.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;
}

现在从我的应用程序中我也想传递函数名。

例如。应用程序.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)

所以在我正在使用的应用程序中,我只需要写这一行

应用程序.cpp

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

我想写类似的

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

对于__FUNCTION__功能。我不希望用户每次都写FILELINEFUNCTION 。

4

2 回答 2

2

改用类中的这个函数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())
于 2013-08-30T18:20:18.987 回答
0

如果您无法修改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__))
于 2013-08-30T14:12:08.250 回答