3

我的应用程序有一个简单的记录器。这是一个(简化的)界面:

class ILogger
{
public:

    virtual void LogUnsafe(const LogPriority& priority, const boost::format& message) = 0;

    virtual void Log(const LogPriority& priority, const boost::format& message)
    {
        if (priority <= logPriority_)
        {
            std::unique_lock<std::mutex> lock(loggerMutex_);
            LogUnsafe(priority, message);
        }
    }

    void Log(const LogPriority& priority, const std::string& message)
    {
        Log(priority, boost::format(message));
    }

    template<typename T, typename... Args>
    void Log(const LogPriority& priority, boost::format &format, const T &v, Args... args)
    {
        Log(priority, boost::format(format) % v, args ...);
    }

    template<typename... Args>
    void Log(const LogPriority& priority, const char *format, Args... args)
    {
        boost::format fmt(format);
        Log(priority, fmt, args ...);
    }
};

现在我需要(为了便于错误检测)在每条日志消息中包含行和功能信息(使用__LINE__and __FUNCTION__)。合理地它应该作为函数参数传递。而且,像往常一样,我不想在每次编写日志消息时都输入所有这些宏。所以我在这里遇到了麻烦。我怎样才能优雅地将它们传递给日志功能,而无需在每条日志消息中明确写入?

提前致谢。

4

2 回答 2

4

I find that the "nicest" way to do this is to use a log object that is created via a macro as Neil explained above. The "nice" thing about it is that it encapsulates all the information available at the site and so it can be passed to different loggers. For example you can have a chain of "loggers" that send it over the network, send it to disk and to a system monitor (like Windows Event Log). Also you can then use a producer-consumer logging thread to boost performance.

class LogEntry{

    LogEntry(const boost::format& traceMsg, const unsigned int lineNumber, const std::string& file){
        //set members
    }

    std::string print(){
        // Do print logic... 
    }

    // Getters... Allow the logger instance build its own log from the info.
}

then use macros:

#define LOG( format ) sendToLogQueue( LogEntry( format, __LINE__, std::string(__FILE__) ) );
于 2013-05-13T10:40:35.507 回答
3

传统的方法是将您的日志调用包装在一个宏中,并且只在代码中使用该宏。

例如

#ifdef NDEBUG
#define LOG(priority, message) \
   Log(priority,message)
...
#else
#define LOG(priority, message) \
   Log(priority, message, __FILE__, __LINE__)
...
#endif

void function()
{
   LOG(PRI1, "Message");
}

然后总是使用 LOG 宏。

于 2013-05-13T10:21:11.143 回答