WriteLog(...)函数在C ++中

时间:2010-09-11 04:57:19

标签: c++ logging iostream

我正试图找到一种从C ++进行日志记录的好方法。我目前的解决方案是:

ostream & GetLog() { if( output == NULL ) throw error; return *output; }

输出在某处定义,可以是文件或其他任何内容。这很好,但是如果没有分配输出,除了抛出错误之外我不会做任何其他事情。此外,我的程序是多线程的,我需要获取一个锁,以便正确检查输出是否为NULL,然后写入它,如果不是。理想情况下,使用GetLog()的任何代码都应该获得该锁:

{
    LockLog lock;
    if( HasLog() )
        GetLog() << "My dog ate " << n << " cookies!" << endl;
}

这对我来说似乎过于冗长。我想做一些像

这样的事情
GetLog() << "My dog ate " << n << " cookies!" << endl;

并且在未分配日志(以及锁定)或类似

的函数时使其无错误地工作
WriteLog( "My dog ate " << n << " cookies!" << endl );

我知道使用C printf语法可以使用变量参数函数来完成。有没有办法用C ++语法执行此操作,并且没有宏会强制我公开GetLog,HasLog和LockLog函数?

4 个答案:

答案 0 :(得分:2)

像这样?

class Log {
    class buffer {
        buffer(...);
        ~buffer() {
            Lock lock(mutex);
            // write in destrcutor
        }
        string data;
        Mutex &mutex;
    };
    Mutex mutex;
...
};

template<class T>
Log::buffer operator<<(Log& l, T t) {
    return t;
}

template<class T>
Log::buffer& operator<<(Log::buffer& b, T t) {
    return b += t;
}

Log log;

log << "blah" << 6;

答案 1 :(得分:1)

对于格式化,您可以尝试使用boost :: format

http://beta.boost.org/doc/libs/1_44_0/libs/format/index.html

答案 2 :(得分:0)

根据经验,我会编写一个函数,它接受一个字符串(或字符串列表),并锁定/记录函数内部。将格式保留在实际日志记录功能之外,这样就可以确保在一个逻辑日志消息的同一个块中记录所有内容。

你可以像我一样处理格式化,即:使用printf样式的构造函数创建一个字符串派生类,并使用它内联。

所以,例如:

class PFString : public string
{
public:
    PFString( const char* pcszFormat, ... )
    { ... }
};

Log( PFString( "something with number %d", 42 ) );

当然,您也可以自由地格式化字符串(例如:C ++运算符样式语法,资源字符串格式等)。

答案 3 :(得分:0)

使用log4cxx,这是

  

从C ++进行日志记录的好方法

您不太可能及时匹配。即使现在看起来有点矫枉过正,您可能会发现您的诊断需求会随着系统的增长而增长,从而使得日志记录组件成为一开始就没有设想过的时间段。

当我使用设计良好,功能强大的框架(参见Boost,STL)时,我发现我既节省了时间又从更好的开发人员那里学习了很好的设计。