我正在编写程序时突然出现一个疯狂的想法:在我的程序中创建日志系统的最佳方法是什么?我的意思是如何将日志保存在代码中的任何位置(当然不包括头文件)?就像是
myLogs << "Ups, somthing failed :(";
你知道,早些时候我只是打开文件并保存我想要的,但现在我想以专业的方式进行:DI 正在考虑将由所有其他类继承的类,但这有点问题。我也想过静态函数,但我不确定它是如何工作的。
我正在编写程序时突然出现一个疯狂的想法:在我的程序中创建日志系统的最佳方法是什么?我的意思是如何将日志保存在代码中的任何位置(当然不包括头文件)?就像是
myLogs << "Ups, somthing failed :(";
你知道,早些时候我只是打开文件并保存我想要的,但现在我想以专业的方式进行:DI 正在考虑将由所有其他类继承的类,但这有点问题。我也想过静态函数,但我不确定它是如何工作的。
没有一个简单的答案;这取决于应用程序。我参与过一些非常大的项目,您可以在其中为不同的子系统配置不同的日志记录;这样的系统在较小的应用程序中将是多余的。如果应用程序必须长时间保持运行,这也会有所不同;在这种情况下,您需要在不停止应用程序的情况下重新配置日志。
但是,一般来说,您或多或少需要一个日志配置文件,指定不同级别的日志记录,以及如何处理日志消息。您还需要确保在没有日志记录时执行最少的操作。我使用的一种解决方案是为每个可用操作(写入文件、发送电子邮件或发送到系统日志)维护各种流缓冲区。然后,我将有一个按日志级别索引的 ostream* 表;如果该级别有任何日志记录,我将创建一个 streambuf 转发到所有必要的操作 streambuf,并将使用它的 ostream 的地址放入表中。这些特殊的 streambuf 还具有启动和停止每个日志记录的功能:启动记录的将使用文件名和行号调用,并且停止记录的将刷新每个托管流。如果给定级别上没有日志记录,则 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__ )
如果要自动插入文件名和行号,则必须使用宏。
创建一个类,并重载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";
}
不确定我是否完全理解这个问题,但我所做的是使用 WM_SETTEXT 消息(然后是另一个自定义消息来提交数据)将日志数据发送到另一个应用程序 - 您还需要编写一个基本的侦听器应用程序将读取和存储数据,最好在列表框之类的控件中。这非常快,因为它不涉及文件系统、管道、套接字等。您还可以在头文件中使用条件编译(由#define/#ifdef 指令控制)来打开或关闭日志记录。