來自mooon的最簡單的日誌類CSimpleLogger

來源:互聯網
上載者:User
/** * 單個標頭檔,可即時獨立使用 ,只要定義了宏NOT_WITH_MOOON,即不依賴於mooon * 簡單的寫日誌類,非安全執行緒,提供按大小滾動功能 * 不追求功能,也不追求效能,只求簡單,若要功能強、效能高,可以使用CLogger * * 使用方法: * 1) 構造一個 CSimpleLogger對象 *     CSimpleLogger logger(".", "test.log", 1024*1024, 10); * 2) 調用print方法寫日誌 *    logger. print("%s\n", "test"); */#ifndef MOOON_SYS_SIMPLE_LOGGER_H#define MOOON_SYS_SIMPLE_LOGGER_H// 只要定義了NOT_WITH_MOOON宏,// 則本檔案和mooon無任何關係,方便整合到自己的代碼中 #define NOT_WITH_MOOON#if !defined(NOT_WITH_MOOON)#include <sys/config.h>#endif // NOT_WITH_MOOON#include <stdio.h>#include <stdarg.h>#include <time.h>#include <sstream>#if !defined(NOT_WITH_MOOON)SYS_NAMESPACE_BEGIN#endif // NOT_WITH_MOOON/***  * 萬能型類型轉換函式  */template <typename AnyType>inline std::string any2string(AnyType any_value){    std::stringstream result_stream;    result_stream << any_value;    return result_stream.str();}/***  * 取目前時間,和date_util.h有重複,但為保持simple_logger.h的獨立性,在所難免  */inline void get_current_datetime(char* datetime_buffer, size_t datetime_buffer_size){    struct tm result;    time_t now = time(NULL);    localtime_r(&now, &result);    snprintf(datetime_buffer, datetime_buffer_size        ,"%04d-%02d-%02d %02d:%02d:%02d"        ,result.tm_year+1900, result.tm_mon+1, result.tm_mday        ,result.tm_hour, result.tm_min, result.tm_sec);}class CSimpleLogger{public:    /***      * 構造一個CSimpleLogger,並建立或開啟記錄檔      * @log_dir 日誌存放的目錄,不需要以斜杠結尾,目錄必須已經存在      * @filename 日誌的檔案名稱,不包含目錄部分,      *           由log_dir和filename共同組成記錄檔路徑      * @log_size 每個記錄檔的大小,單位為位元組數,如果小於1024,則會被強製為1024      * @log_numer 日誌滾動的個數      * @record_size 單條日誌的大小,超過會被截斷,單位為位元組數,如果小於1024,則會被強製為1024      */    CSimpleLogger(const std::string& log_dir                 ,const std::string& filename                 ,unsigned int log_size = 1024*1024*100                 ,unsigned char log_numer = 10                 ,unsigned short record_size = 8192);    ~CSimpleLogger();    /** 記錄檔是否建立或開啟成功 */    bool is_ok() const;        /** 輸出日誌,象printf一樣使用,不自動加分行符號 */    void print(const char* format, ...);    /** 重新整理日誌,因為使用FILE是帶緩衝的 */    void flush();private:    void reset();    /** 複位狀態值 */    void roll_log(); /** 滾動日誌 */private:    FILE* _fp;                    /** 當前正在寫的記錄檔描述符 */    char* _log_buffer;            /** 存放日誌的Buffer */    int _bytes_writed;            /** 已經寫入的位元組數 */    std::string _log_dir;         /** 日誌存放目錄 */    std::string _filename;        /** 記錄檔名,不包含目錄部分 */    unsigned int _log_size;       /** 單個記錄檔的大小 */    unsigned char _log_numer;     /** 日誌滾動的個數 */    unsigned short _record_size;  /** 單條日誌的大小,單位為位元組數 */};inline CSimpleLogger::CSimpleLogger(                     const std::string& log_dir                     ,const std::string& filename                    ,unsigned int log_size                    ,unsigned char log_numer                    ,unsigned short record_size) :_fp(NULL) ,_log_buffer(NULL) ,_bytes_writed(0) ,_log_dir(log_dir) ,_filename(filename) ,_log_size(log_size) ,_log_numer(log_numer) ,_record_size(record_size){    std::string log_path = log_dir + std::string("/") + filename;    _fp = fopen(log_path.c_str(), "a");        if (_fp != NULL)    {        if (-1 == fseek(_fp, 0, SEEK_END))        {            // 失敗,將不會寫日誌            fclose(_fp);            _fp = NULL;        }        else        {            // 取得已有大小            _bytes_writed = ftell(_fp);            // 不能太小氣了                      if (_log_size < 1024)            {                _log_size = 1024;            }                        // 同樣不能太小氣            if (_record_size < 1024)            {                _record_size = 1024;            }                        _log_buffer = new char[_record_size];        }    }}inline CSimpleLogger::~CSimpleLogger(){    if (_fp != NULL)        fclose(_fp);            delete []_log_buffer;}inline bool CSimpleLogger::is_ok() const{    return _fp != NULL;}inline void CSimpleLogger::print(const char* format, ...){    if (_fp != NULL)    {        va_list ap;        va_start(ap, format);        char datetime_buffer[sizeof("2012-12-21 00:00:00")]; // 剛好世界末日        get_current_datetime(datetime_buffer, sizeof(datetime_buffer));        vsnprintf(_log_buffer, _record_size, format, ap);        int bytes_writed = fprintf(_fp, "[%s]%s", datetime_buffer, _log_buffer);        if (bytes_writed > 0)            _bytes_writed += bytes_writed;        if (_bytes_writed > static_cast<int>(_log_size))        {            roll_log();        }        va_end(ap);    }}inline void CSimpleLogger::roll_log(){    std::string new_path; // 滾動後的檔案路徑,包含目錄和檔案名稱    std::string old_path; // 滾動前的檔案路徑,包含目錄和檔案名稱        reset(); // 輪迴,一切重新開始        // 曆史滾動    for (int i=_log_numer-1; i>0; --i)    {        new_path = _log_dir + std::string("/") + _filename + std::string(".") + any2string(i);        old_path = _log_dir + std::string("/") + _filename + std::string(".") + any2string(i-1);        if (0 == access(old_path.c_str(), F_OK))        {            rename(old_path.c_str(), new_path.c_str());        }    }    if (_log_numer > 0)    {        // 當前滾動        new_path = _log_dir + std::string("/") + _filename + std::string(".1");        old_path = _log_dir + std::string("/") + _filename;        if (0 == access(old_path.c_str(), F_OK))        {            rename(old_path.c_str(), new_path.c_str());        }    }    // 重新建立    _fp = fopen(old_path.c_str(), "w+");}inline void CSimpleLogger::reset(){    _bytes_writed = 0;    if (_fp != NULL)    {        fclose(_fp);        _fp = NULL;    }}inline void CSimpleLogger::flush(){    if (_fp != NULL)        fflush(_fp);}/***  * 測試代碼#include "simple_logger.h"int main(){    CSimpleLogger logger(".", "test.log", 10240);    for (int i=0; i<100000; ++i)        logger.print("%d ==> abcdefghijklmnopqrestuvwxyz.\n", i);            return 0;}*/#if !defined(NOT_WITH_MOOON)SYS_NAMESPACE_END#endif // NOT_WITH_MOOON#endif // MOOON_SYS_SIMPLE_LOGGER_H

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.