glog的編譯和使用


glog是google提供的一個輕量級日志庫,有chromium開發經驗的人都會發現,它和base庫中的日志庫非常像,其實base庫中的日志庫比它更加輕量級。glog在日常開發中的使用非常廣泛。這里介紹下它的編譯和基本使用方法。

1. 下載

通過git從github拉取最新版本代碼:

git clone https://github.com/google/glog.git

2.編譯

2.1 Ubuntu

直接在工程目錄下運行

./autogen.sh && ./configure && make

編譯完后就會在libs目錄下生成libglog.so動態庫和libglog.a動態庫,搭配src/glog目錄下的.h頭文件使用即可。

2.2 Windows

windows上需要通過cmake來編譯。首先要配置cmake環境,這里就不再贅述。
為了不污染代碼,我們先創建一個cmake_build文件夾,在里面執行:

cmake ..

運行完cmake命令后,會生成glog.sln文件,雙擊打開,它便是VS解決方案。然后直接運行編譯,這樣會直接生成lib靜態庫。
為了生成dll動態庫,我們需要使用cmake-gui,勾選上"BUILD_SHARED_LIBS"選項,這樣生成的glog工程默認就是dll庫。
image.png
編譯完后就會在Debug或Release目錄生成lib靜態庫或者dll動態庫。
頭文件會自動放在glog目錄中(缺了log_severity.h):
image.png
這里是編譯好的dll庫:glog.zip

3. glog使用

3.1 日志級別

glog和chromium中的日志級別一樣,分為:

  • INFO(=0)
  • WARNING(=1)
  • ERROR(=2)
  • FATAL(=3)

使用時直接:

LOG(INFO) << "-------------123";

同樣在DBUG模式下可以使用DLOG來設置調試日志:

DLOG(INFO) << "-------------123";

3.2 初始化日志配置

1.初始化

要將日志輸出到文件,需要先對日志庫進行初始化:

google::InitGoogleLogging(argv[0]);  //括號內是程序名

默認會將日志輸出到"C:\Users\user\AppData\Local\Temp"目錄下。

2.關閉日志庫

有了初始化,那相對的在退出程序前,也需要對日志庫進行關閉操作:

google::ShutdownGoogleLogging();

3.設置日志保存目錄

注意這個目錄必須是已經存在,否則不能生成日志文件:

FLAGS_log_dir = "D:\\Logs";

4.幾個參數

FLAGS_logtostderr = true;  //設置日志消息是否轉到標准輸出而不是日志文件
FLAGS_alsologtostderr = true;  //設置日志消息除了日志文件之外是否輸出到標准輸出
FLAGS_colorlogtostderr = true;  //設置記錄到標准輸出的顏色消息(如果終端支持)
FLAGS_log_prefix = true;  //設置日志前綴是否應該添加到每行輸出
FLAGS_logbufsecs = 0;  //設置可以緩沖日志的最大秒數,0指實時輸出
FLAGS_max_log_size = 10;  //設置最大日志文件大小(以MB為單位),超過會對文件進行分割
FLAGS_stop_logging_if_full_disk = true;  //設置是否在磁盤已滿時避免日志記錄到磁盤
FLAGS_minloglevel = google::GLOG_WARNING;	//設置最小處理日志的級別

5.幾個函數

google::SetLogDestination(google::GLOG_INFO, "log/prefix_");  //設置特定嚴重級別的日志的輸出目錄和前綴。第一個參數為日志級別,第二個參數表示輸出目錄及日志文件名前綴
google::SetLogFilenameExtension("logExtension");  //在日志文件名中級別后添加一個擴展名。適用於所有嚴重級別
google::SetStderrLogging(google::GLOG_INFO);  //大於指定級別的日志都輸出到標准輸出

4. 修改glog

4.1 日志輸出格式

習慣了chromium風格的日志,對glog日志很不習慣,因此,我們可以修改glog日志的輸出格式。
首先,將logging.cc中的LogFileObject::Write函數里,創建日志文件時必會寫入的日志格式說明修改一下:

//Write a header message into the log file
    ostringstream file_header_stream;
    file_header_stream.fill('0');
    file_header_stream << "Log file created at: "
                      << 1900+tm_time.tm_year << '/'
                      << setw(2) << 1+tm_time.tm_mon << '/'
                      << setw(2) << tm_time.tm_mday
                      << ' '
                      << setw(2) << tm_time.tm_hour << ':'
                      << setw(2) << tm_time.tm_min << ':'
                      << setw(2) << tm_time.tm_sec << '\n'
                      << "Running on machine: "
                      << LogDestination::hostname() << '\n'
                      << "Log line format: [pid:tid:mmdd/hh:mm:ss.uuuuuu:severity:file(line)] msg" << '\n';

然后,將LogMessage::Init里每條日志的前綴修改下:

    //stream() << LogSeverityNames[severity][0]
    //         << setw(2) << 1+data_->tm_time_.tm_mon
    //         << setw(2) << data_->tm_time_.tm_mday
    //         << ' '
    //         << setw(2) << data_->tm_time_.tm_hour  << ':'
    //         << setw(2) << data_->tm_time_.tm_min   << ':'
    //         << setw(2) << data_->tm_time_.tm_sec   << "."
    //         << setw(6) << data_->usecs_
    //         << ' '
    //         << setfill(' ') << setw(5)
    //         << static_cast<unsigned int>(GetTID()) << setfill('0')
    //         << ' '
    //         << data_->basename_ << ':' << data_->line_ << "] ";

    stream() << '[' << getpid() << ":" << static_cast<unsigned int>(GetTID()) << ":"
             << std::setfill('0')
             << std::setw(2) << 1 + data_->tm_time_.tm_mon
             << std::setw(2) << data_->tm_time_.tm_mday
             << '/'
             << std::setw(2) << data_->tm_time_.tm_hour
             << std::setw(2) << data_->tm_time_.tm_min
             << std::setw(2) << data_->tm_time_.tm_sec
             << '.'
             << std::setw(6) << data_->usecs_
             << ':'
             << LogSeverityNames[severity] << ":" << data_->basename_ << "(" << data_->line_ << ")] ";

同樣修改下LogSink::ToString里的格式:

  //stream << LogSeverityNames[severity][0]
  //       << setw(2) << 1+tm_time->tm_mon
  //       << setw(2) << tm_time->tm_mday
  //       << ' '
  //       << setw(2) << tm_time->tm_hour << ':'
  //       << setw(2) << tm_time->tm_min << ':'
  //       << setw(2) << tm_time->tm_sec << '.'
  //       << setw(6) << usecs
  //       << ' '
  //       << setfill(' ') << setw(5) << GetTID() << setfill('0')
  //       << ' '
  //       << file << ':' << line << "] ";
  stream << '[' << getpid() << ":" << GetTID() << ":"
      << std::setfill('0')
      << std::setw(2) << 1 + tm_time->tm_mon
      << std::setw(2) << tm_time->tm_mday
      << '/'
      << std::setw(2) << tm_time->tm_hour << ':'
      << std::setw(2) << tm_time->tm_min << ':'
      << std::setw(2) << tm_time->tm_sec << '.'
      << '.'
      << std::setw(6) << usecs
      << ':'
      << LogSeverityNames[severity] << ":" << file << "(" << line << ")] ";

修改后的日志輸出如下:
image.png
和chromium風格是一致的。

4.2 日志文件名

默認glog會在日志目錄下給每個級別的日志都會創建一個日志文件,且每次啟動應用程序都會修改日志文件名(因為進程名變化),雖然能夠起到過濾日志的作用,但是這樣也會導致日志文件過多。我希望各種級別的日志都存放在一個文件中就行。
這部分的修改比較多,由於原本glog的邏輯時不同級別的日志分別處理,而我的目的是將它們統一放到一個文件中,這違背了它的設計原則,因此修改后很多功能可能都會受影響。因此,我封裝了一層接口:

LOG_DLL_DECL int InitLogger(
    const std::string& logName = "",
    const std::string& logPath = "",
    const google::LogSeverity minSeverity = google::GLOG_INFO,
    const unsigned int fileMaxSize = 10);

LOG_DLL_DECL void ReleaseLogger();

使用這兩個設置接口就沒有問題。

代碼: https://github.com/243286065/glog.git (分支:chromium_style)
這里是已經編譯好的windows win32庫:glog.zip

使用實例:

#include <iostream>

#include "glog/logger.h"
#define APP_NAME "GlogTest"

int main(int argc, char* argv[])
{
    InitLogger(APP_NAME, "D:\\logs\\", google::GLOG_INFO);

    LOG(INFO) << "-------------123";
    LOG(WARNING) << "-------------123";
    LOG(ERROR) << "-------------123";
    std::cout << "Hello World!\n"; 


    ReleaseLogger();
}

最后,感覺這樣整,還不如直接把chromium的base庫中的日志庫拿出來用~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM