• 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:UsersuserAppDataLocalTemp"目录下。

    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 << '
    '
                          << "Running on machine: "
                          << LogDestination::hostname() << '
    '
                          << "Log line format: [pid:tid:mmdd/hh:mm:ss.uuuuuu:severity:file(line)] msg" << '
    ';
    

    然后,将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!
    "; 
    
    
        ReleaseLogger();
    }
    

    最后,感觉这样整,还不如直接把chromium的base库中的日志库拿出来用~~~

  • 相关阅读:
    java的初始化
    java继承
    java多态
    static、final关键字
    java的清理
    java访问权限控制
    java对象与引用及参数传递
    java学习--学生成绩管理系统
    The Nth Item 南昌网络赛(递推数列,分段打表)
    Random Access Iterator 徐州网络赛(树形dp)
  • 原文地址:https://www.cnblogs.com/xl2432/p/11825966.html
Copyright © 2020-2023  润新知