C++簡単なログログ出力を実現

10108 ワード

テキストリンク:https://blog.csdn.net/qq_21334991/article/details/79282622本文は原文に基づいて、自分の思考を結びつけて、説明を増やしました.1、まずログの使用ログを见て、プログラムのデバッグ、エラーなどの情报をファイル(あるいは印刷)に保存することができて、プログラムのデバッグと故障の照会などに便利です.
#include 
#include "Logger.h"
using namespace std;
int main(int argc, char *argv) {
    LOG(INFO)<<"helloworld";
    return 0;
}

実行結果は次のとおりです.ログを使用する場合は、次のような文を追加するだけです.
LOG(INFO)<<"helloworld";
//     ,                   
//  :LOG(  )<

2、ログ出力の実現原理上及びログを使用する場合、コードに以下のような文を加えるだけでよい:LOG(INFO)<出力ストリームである以上、実装は出力ストリームオブジェクトによって実現されるに違いない.LOG(INFO)ストリームオブジェクトの実装コードは以下の通りである.
//LOG()     :
#define LOG(log_rank)   \
Logger(log_rank).start(log_rank, __LINE__,__FUNCTION__)

//Logger  start      :
std::ostream& Logger::start(log_rank_t log_rank,
                            const int line,
                            const std::string&function)
{
    time_t tm;
    time(&tm);
    char time_string[128];
    ctime_r(&tm, time_string);
    return getStream(log_rank) << time_string
                               << "function (" << function << ")"
                               << "line " << line<<" "
                               <<std::flush;
}


上記のコードから分かるように、ログ出力の原理は、LOG(INFO)がマクロ関数であり、マクロ展開がLoggerクラスオブジェクトを構築し、そのオブジェクトのstart関数を呼び出し、start関数戻りタイプがストリームオブジェクトタイプであるため、LOG(INFO)が出力ストリームオブジェクトを取得し、そのオブジェクトに基づいて出力することができる.3、ログに関するいくつかの重要な問題(1)どのように出力するか(前述したように、ストリームオブジェクトを取得することによって)(2)出力オブジェクト(ファイル保存に出力するか、標準出力オブジェクトディスプレイに出力するか)(3)ログのレベル(必要に応じて出力されるログレベルが異なり、異なるレベルのログを分類して保存できる)(4)ログファイルの保存(ログがファイルに保存されている場合は、ファイルが保存されているパスを示す必要があります)
次に、Loggerクラスと上記のいくつかの重要な問題を組み合わせて分析します.
class Logger {
    friend void initLogger(const std::string& info_log_filename,
                           const std::string& warn_log_filename,
                           const std::string& erro_log_filename);
 
public:
    //    
    Logger(log_rank_t log_rank) : m_log_rank(log_rank) {};
 
    ~Logger();
    ///
    /// \brief                   ,   ,    
    /// \param log_rank      
    /// \param line        
    /// \param function        
    static std::ostream& start(log_rank_t log_rank,
                               const int line,
                               const std::string& function);
 
private:
    ///
    /// \brief               
    ///
    static std::ostream& getStream(log_rank_t log_rank);
 
    static std::ofstream m_info_log_file;                   ///<         
    static std::ofstream m_warn_log_file;                  ///<         
    static std::ofstream m_error_log_file;                  ///<         
    log_rank_t m_log_rank;                             ///<         
};

ロガーに含まれるメンバー関数と変数は以下の通りである:(1)共通インタフェースロガー(log_rank_t log_rank):関数を構築し、ロガークラスオブジェクトを構築し、オブジェクトの印刷レベルstatic std::ostream&start():出力ストリームオブジェクトの取得(2)プライベートメンバー関数static std::ostream&getStream(log_rank_t log_rank)ログ出力位置(ディスプレイorファイル)に基づいて、取得したメンバー関数が標準出力オブジェクトcoutかファイルストリームオブジェクトm_info_log_file/m_warn_log_file/m_error_log_fileかを決定する必要がある(3)メンバ変数static std::ofstream m_info_log_file;///<情報日の出力ストリームstatic std::ofstream m_warn_log_file;//<警告情報の出力ストリームstatic std::ofstream_error_log_file;//<エラー情報の出力ストリームlog_rank_t m_log_rank;//<ログの情報のレベル(4)友元関数friend void initLogger(const std::string& info_log_filename, const std::string& warn_log_filename, const std::string& erro_log_filename); 主に異なるレベルのログの出力パスを指定します.