如何在我的程序中创建日志系统?

时间:2012-07-09 10:05:14

标签: c++ logging project-management

我正在编写程序时突然出现了一个想法:在我的程序中创建日志系统的最佳方法是什么?我的意思是如何在我的代码中的任何地方保存日志(当然不包括头文件)?像

这样的东西
myLogs << "Ups, somthing failed :(";

你知道,早些时候我只是打开文件并保存我想要的东西,但现在我想以专业的方式做到这一点:D我正在考虑将被所有其他类继承的类,但它有点问题。我也考虑过静态功能,但我不确定它是如何工作的。

3 个答案:

答案 0 :(得分:3)

没有一个简单的答案;这取决于应用程序。我有 在一些非常大的项目上工作,你可以配置日志记录 不同的子系统不同;这样的系统会有点矫枉过正 较小的应用程序。如果应用程序也有所不同 必须保持很长一段时间;在这种情况下,你会想要的 一些用于重新配置日志而不停止日志的规定 应用

但是,或多或少,您需要一个日志配置文件, 指定不同级别的日志记录以及如何处理日志 消息。您还需要确保执行最少的操作 什么时候没有记录。我用过的一个解决方案就是保持各种各样的方法 每个可用操作的streambufs(写入文件,发送电子邮件, 或发送到syslog)。然后,我将有一张ostream表,由...索引 日志级别;如果有该级别的任何日志记录,我将创建一个 streambuf转发所有必要的行动streambuf,和 把表中使用它的ostream的地址放在一起。这些特别的 streambuf还具有启动和停止每个记录记录的功能: 将使用filename和linenumber调用启动记录的那个, 并且停止记录的那个将刷新每个托管流。 如果在给定级别上没有记录,则ostream指针为空。

基本记录器是:

class Logger
{
    std::ostream* myDest;
    int* myUseCount;
public:
    Logger( int level, char const* filename, int lineNumber )
        : myDest( ourLogTable[level] )
        , myUseCount( new int( 1 ) )
    {
        if ( myDest != NULL ) {
            myDest->rdbuf()->startLogRecord( filename, lineNumber );
        }
    }

    Logger( Logger const& other )
        : myDest( other.myDest )
        , myUseCount( other.myUseCount )
    {
        ++ *myUseCount;
    }

    ~Logger()
    {
        -- *myUseCount;
        if ( *myUseCount == 0 && myDest != NULL ) {
            myDest->flush();
        }
    }

    template <typename T>
    Logger& operator<<( T const& obj )
    {
        if ( myDest != NULL ) {
            *myDest << obj;
        }
    }
};

(使用C ++ 11,您应该使用移动语义而不是我的引用 数数。更简单。)

最后,您通过宏调用记录器:

#define LOG(level) Logger( level, __FILE__, __LINE__ )

如果要自动插入,则需要使用宏 文件名和行号。

答案 1 :(得分:2)

创建一个类,并重载operator<<以实现写入文件或任何你想要的内容。

#include <fstream>
#include <iostream>

using namespace std;

class logger
{
public:
    void operator<<( const std::string & input );
}MyLogger;

void logger::operator <<(const string &input)
{
    std::ofstream of("filename.txt");
    of << input;
    of.close();
}

int main()
{
    MyLogger<<"sometext";
}

答案 2 :(得分:0)

我不确定我是否完全理解这个问题,但我所做的是将日志数据发送到另一个应用程序,使用WM_SETTEXT消息(然后另一个自定义消息提交数据) - 您还需要编写一个基本的将要读取和存储数据的监听器应用程序,最好是在列表框之类的控件中。这非常快,因为它不涉及文件系统,管道,套接字等。您还可以在头文件中使用条件编译(由#define / #ifdef指令控制)来打开或关闭日志。