0

プログラムを書いていたとき、突如として突飛な考えが浮かびました: 私のプログラムでログシステムを作成する最良の方法は何ですか? コード内の任意の場所にログを保存するにはどうすればよいですか (もちろん、ヘッダー ファイルを除く)。何かのようなもの

myLogs << "Ups, somthing failed :(";

ご存知のように、以前はファイルを開いて必要なものを保存しましたが、今はプロの方法でそれを行いたいと思います:DIは他のすべてのクラスに継承されるクラスについて考えていましたが、ちょっと問題があります. 静的関数も考えましたが、どのように機能するかわかりません。

4

3 に答える 3

3

単純な答えはありません。アプリケーションによって異なります。私はいくつかの非常に大きなプロジェクトに取り組んできました。そこでは、サブシステムごとに異なるロギングを構成することができました。このようなシステムは、小規模なアプリケーションではやり過ぎです。また、アプリケーションを長時間稼働させておく必要がある場合にも違いがあります。このような場合、アプリケーションを停止せずにログを再構成するための何らかの準備が必要になります。

ただし、多かれ少なかれ一般的には、さまざまなレベルのログ記録と、ログ メッセージの処理方法を指定するログ構成ファイルが必要になります。また、ログが記録されていないときに最小限のアクションを実行するようにする必要があります。私が使用した 1 つの解決策は、利用可能なアクション (ファイルへの書き込み、電子メールの送信、または syslog への送信) ごとにさまざまな streambuf を維持することです。次に、ログ レベルでインデックス付けされた ostream* のテーブルを作成します。そのレベルのログがあれば、必要なすべてのアクション ストリームバッファに転送するストリームバッファを作成し、それを使用する ostream のアドレスをテーブルに入れます。これらの特別な streambuf には、各ロギング レコードを開始および停止する関数もあります。記録を開始する関数は、ファイル名と行番号で呼び出されます。レコードを停止するものは、管理された各ストリームをフラッシュします。特定のレベルでログが記録されていない場合、ostream ポインターは null です。

基本的なロガーは次のとおりです。

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__ )

ファイル名と行番号を自動的に挿入する場合は、マクロの使用が必要です。

于 2012-07-09T11:12:53.077 に答える
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";
}
于 2012-07-09T10:21:15.657 に答える
0

質問を正確に理解しているかどうかはわかりませんが、私が行ったことは、WM_SETTEXTメッセージを使用してログデータを別のアプリケーションに送信することです(そして、別のカスタムメッセージを使用してデータをコミットします)-基本的なリスナーアプリケーションも作成する必要がありますできればリストボックスのようなコントロールにデータを読み込んで保存します。これは、ファイル システム、パイプ、ソケットなどを必要としないため、非常に高速です。ヘッダー ファイル (#define/#ifdef ディレクティブで制御) で条件付きコンパイルを使用して、ログのオンとオフを切り替えることもできます。

于 2012-07-09T10:21:35.497 に答える