glog和gflags的使用

article/2025/10/19 13:32:30

glog:日志输出

支持debug功能

      glog提供特定的宏只在debug模式下生效。以下分别对应LOG、LOG_IF、DLOG_EVERY_N操作的专用宏。

   DLOG(INFO) << "Found cookies";

   DLOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";

   DLOG_EVERY_N(INFO, 10) << "Got the " << COUNTER << "th cookie";

判定大小关系: CHECK_EQ, CHECK_NE, CHECK_LE, CHECK_LT, CHECK_GE, CHECK_GT,使用这些宏需要注意类型一致,如果出现类型不一致的,可使用static_cast转换。

判定指针是否为空:CHECK_NOTNULL(some_ptr),可用于对象初始化的时候。

判定字符串是否相等:CHECK_STREQ, CHECK_STRNE, CHECK_STRCASEEQ, CHECK_STRCASENE。可进行大小写敏感或不敏感字符串来分别判定。

判定浮点是否相等或相近:CHECK_DOUBLE_EQ,CHECK_NEAR。这两个宏都需要指定一个可容忍的偏差上限。

gflags:命令行参数解析

将需要的命令行参数使用gflags的宏:DEFINE_xxxxx(变量名,默认值,help-string) 定义在文件当中,注意全局域哦。gflags支持以下类型:

  • DEFINE_bool: boolean
  • DEFINE_int32: 32-bit integer
  • DEFINE_int64: 64-bit integer
  • DEFINE_uint64: unsigned 64-bit integer
  • DEFINE_double: double
  • DEFINE_string: C++ string
google::ParseCommandLineFlags(&argc, &argv, true);
第三个参数的作用:
如果设为true,则该函数处理完成后,argv中只保留argv[0],argc会被设置为1。
如果为false,则argv和argc会被保留,但是注意函数会调整argv中的顺序。

这样,在后续代码中可以使用FLAGS_变量名访问对应的命令行参数了

最后,编译成可执行文件之后,用户可以使用:executable --参数1=值1 --参数2=值2 ... 来为这些命令行参数赋值。

这里值得注意的是bool类型命令行参数,除了可以使用--xxx=true/false之外,还可以使用--xxx和--noxxx后面不加等号的方式指定true和false

 

在其他文件中使用定义的flags变量:有些时候需要在main之外的文件使用定义的flags变量,这时候可以使用宏定义DECLARE_xxx(变量名)声明一下(就和c++中全局变量的使用是一样的,extern一下一样)

  • DECLARE_bool: boolean
  • DECLARE_int32: 32-bit integer
  • DECLARE_int64: 64-bit integer
  • DECLARE_uint64: unsigned 64-bit integer
  • DECLARE_double: double
  • DECLARE_string: C++ string
    在gflags的doc中,推荐在对应的.h文件中进行DECLARE_xxx声明,需要使用的文件直接include就行了。

 

  1. 定制你自己的help信息与version信息:(gflags里面已经定义了-h和--version,你可以通过以下方式定制它们的内容)
    • version信息:使用google::SetVersionString设定,使用google::VersionString访问
    • help信息:使用google::SetUsageMessage设定,使用google::ProgramUsage访问
    • 注意:google::SetUsageMessage和google::SetVersionString必须在google::ParseCommandLineFlags之前执行

main.cc:

#include <glog/logging.h>
#include <gflags/gflags.h>DEFINE_string(file_path, "", "input file path"); // 不一定放在main函数中
DEFINE_bool(verbose, false, "whether to print log"); // 调试开关
DEFINE_double(rate, 2.0, ""); // 代替宏定义int main(int argc, char *argv[]) {google::InitGoogleLogging(argv[0]); // 初始化glogFLAGS_logtostderr = 1;FLAGS_colorlogtostderr = 1;gflags::SetUsageMessage("\nusage: ./test --file_path <file_path>");google::ParseCommandLineFlags(&argc, &argv, true);  // 初始化gflagsstd::string file_path = FLAGS_file_path;if (file_path.empty()) {gflags::ShowUsageWithFlagsRestrict(argv[0], "main");LOG(FATAL) << "file_path is empty !";}CHECK(!FLAGS_file_path.empty()) << "file path is empty";for(int index = 0; index <= 10; ++index) {LOG(INFO) << "index: " << index;LOG_IF(INFO, index > 5) << "  --> index > 5"; // 当index > 5时输出logLOG_EVERY_N(WARNING, 5) << "  --> index % 5 == 0"; // 每隔5次输出一次logLOG_IF_EVERY_N(ERROR, index < 5, 2) << "  --> index < 5, i % 2 == 0"; // 当index < 5时每隔2次输出一次log;LOG_FIRST_N(INFO, 8) << "  --> index < 8"; // 输出前8次log}DLOG(INFO) << "Debug Mode Message!"; // debug模式输出log,release模式不输出google::ShutdownGoogleLogging();return 0;
}

CMakeList.txt: 

cmake_minimum_required(VERSION 2.8)
project(test)set(CMAKE_BUILD_TYPE "Debug") # Debug/Release
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)find_package(gflags REQUIRED)
include_directories(${gflags_INCLUDE_DIR})
find_package(Glog REQUIRED)
include_directories(${GLOG_INCLUDE_DIRS})add_executable(test main.cc)
target_link_libraries(test glog::glog gflags)

$ ./bin/test

test: 
usage: ./test --file_path <file_path>Flags from /home/ubuntu/test/main.cc:-file_path (input file path) type: string default: ""-rate () type: double default: 2-verbose (whether to print log) type: bool default: false
F0601 20:30:42.405541 32641 main.cc:19] file_path is empty !
*** Check failure stack trace: ***@           0x414be6  google::LogMessage::Fail()@           0x414b2a  google::LogMessage::SendToLog()@           0x414466  google::LogMessage::Flush()@           0x417f87  google::LogMessageFatal::~LogMessageFatal()@           0x410daa  main@     0x7fa34acdf830  __libc_start_main@           0x410ba9  _start@              (nil)  (unknown)
Aborted (core dumped)

$ ./bin/test --file_path /home/

 

默认情况下,日志会写入本地/tmp/文件夹中,文件名格式:

<program name>.<host name>.<user name>.log.<Severity level>.<date>-<time>.<pid>

如:在/tmp下生成

main.INFO -> main.ubuntu.alan.log.INFO.20191022-150504.49837

main.ubuntu.alan.log.INFO.20191022-150504.49837

 

默认情况下,GLog还会将ERROR和FATAL错误记录到stderr消息中(会在终端打印出来);

在终端打印出的消息的格式:

<Serverity level><number> <time>.<number> <pid> <file>:<line number> <messages>
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg

如:

I1022 15:05:04.920763 49837 main.cc:20] initial main

glog参数设置:

    FLAGS_log_dir = "./"; // 设置log输出文件夹,默认输出到本地/tmp文件夹下FLAGS_logtostderr = 1; // 设置log输出到stderr,不保存到本地FLAGS_alsologtostderr = 1; // 设置log输出到stderr和本地FLAGS_stderrthreshold = 1; // WARNING以及更高级别的log将会记录到stderr中;(INFO: 0, WARNING: 1, ERROR: 2 FATAL: 3)FLAGS_minloglevel = 0; // 默认是0,INFO以及更高级别的Log将会被记录;(INFO: 0, WARNING: 1, ERROR: 2 FATAL: 3)FLAGS_colorlogtostderr = 1; // 设置记录到标准输出的颜色消息(如果终端支持)FLAGS_log_prefix = true; // 设置日志前缀是否应该添加到每行输出FLAGS_logbufsecs = 0;// 设置可以缓冲日志的最大秒数,0指实时输出FLAGS_max_log_size =10;// 设置最大日志文件大小(以MB为单位)FLAGS_stop_logging_if_full_disk = true; // 设置是否在磁盘已满时避免日志记录到磁盘

可在命令行运行程序时指定这些flag,如$ ./exe  -logtostderr true

在其他文件中使用定义的flags变量:有些时候需要在main之外的文件使用定义的flags变量,这时候可以使用宏定义DECLARE_xxx(变量名)声明一下(就和c++中全局变量的使用是一样的,extern一下一样)

  • DECLARE_bool: boolean
  • DECLARE_int32: 32-bit integer
  • DECLARE_int64: 64-bit integer
  • DECLARE_uint64: unsigned 64-bit integer
  • DECLARE_double: double
  • DECLARE_string: C++ string
    在gflags的doc中,推荐在对应的.h文件中进行DECLARE_xxx声明,需要使用的文件直接include就行了。

参考:https://blog.csdn.net/qq_34347375/article/details/86629421


glog重定向

#include <glog/logging.h>
#include "alan/logger.h"Alan::Logger my_logger;class MyLogSink : public google::LogSink {void send(google::LogSeverity severity,const char*         full_filename,const char*         base_filename,int                 line,const struct ::tm*  tm_time,const char*         message,size_t              message_len) override {thread_local std::string msg;msg.assign(message, message_len);Alan::LogLevel my_level;switch (severity) {case google::GLOG_INFO: my_level = Alan::LogLevel::INFO; break;case google::GLOG_WARNING: my_level = Alan::LogLevel::WARN; break;case google::GLOG_ERROR: my_level = Alan::LogLevel::ERROR; break;case google::GLOG_FATAL: my_level = Alan::LogLevel::FATAL; break;default: my_level = Alan::LogLevel::INFO;}my_logger.Log(my_level, "%%:%%] %%", base_filename, line, msg);}
};static MyLogSink my_log_sink;int main(int argc, char *argv[]) {google::InitGoogleLogging(argv[0]);google::AddLogSink(&my_log_sink);// Avoid duplicate logging to stderr with my_logger.FLAGS_stderrthreshold = google::NUM_SEVERITIES;return 0;
}

 


http://chatgpt.dhexx.cn/article/4P4A9W9h.shtml

相关文章

【gflags】gflags 命令行参数配置库

gflag介绍 google开源的gflags是一套命令行参数解析工具 主要就是用来解析命令行参数&#xff0c;并且支持从文件或者从环境变量中读入参数&#xff0c;功能十分强大 gflag的使用 我们以使用为目标进行讲解&#xff0c;不会进行深入了解&#xff08;其实并不是很难&#xff0c;…

js判断文件类型详解

js判断文件类型详解 通过file的type属性判断 <input type"file" onchange"onchangecb(this)" /> <script> function onchangecb(e) {const file e.files[0];console.log(file.type); } </script>像html中input标签&#xff0c;就是根…

JS——判断变量类型方法汇总

判断变量类型 一、使用typeof判断变量类型二、使用instanceof判断变量的类型三、使用constructor判断变量的类型四、使用Object.prototype.toString.call判断变量的类型五、使用jquery中$.type判断变量的类型。六、总结 在JS中&#xff0c;有 5 种基本数据类型和 1 种复杂数据类…

JavaScript中的类型判断

js中的类型判断 1、使用typeof进行类型判断2、使用 instanceof 判断对象3、使用Array.isArray()判断数组 1、使用typeof进行类型判断 function fun() { }; console.log("数字的类型为&#xff1a;" typeof (1)); console.log("字符串的类型为&#xff1a;&quo…

js:判断数据类型的几种方法

参考文章&#xff1a;JavaScript中判断对象类型的几种方法总结 根据要判断的数据对象&#xff0c;来选用合适的方法 1、原始数据类型 6种&#xff1a;number、string、boolean、undefined、null、symbol 一、typeof let str hello; console.log(typeof str); // string【特…

JS判断数据类型的几种方式

JS中常见的几种数据类型 基本类型&#xff1a;string、boolean、number特殊类型&#xff1a;undefined和null3、引用类型&#xff1a;Array、Date、RegExp… typeof typeof检测基本数据类型时没有问题&#xff0c;但是当其对引用类型进行检测时&#xff0c;会返回object&…

js 精确判断对象的类型

在 JavaScript 里使用 typeof 来判断数据类型&#xff0c;只能区分基本类型&#xff0c;即 “number”&#xff0c;”string”&#xff0c;”undefined”&#xff0c;”boolean”&#xff0c;”object” 五种。 对于数组、函数、对象来说&#xff0c;其关系错综复杂&#xff0c…

JavaScript——判断js数据类型(类型检测)

判断js数据类型&#xff0c;也就是我们说的类型检测&#xff0c;本文提供五种方法&#xff0c;分别是typeof运算符、instanceof操作符、Object.prototype.toString方法、constructor属性、duck type。 1、typeof运算符 typeof算是最常见的了&#xff0c;使用它会返回一个字符…

js判断数据类型常用的6种方法

js判断数据类型常用的方法,不论在开发中开始在面试中,都是经常遇到的问题,尤其是在面试时,当面试官问及js判断数据类型的方法时,回答的越多,说明掌握的广度跟深度越多,感觉自己逼格也越高.废话不多说了,进入正题 常见的判断js数据类型的方法有如下几种 1.最常见的判断方法&am…

js判断数据类型的几种方法

第一种&#xff1a;Object.prototype.toString()方法&#xff1a; 注意这里是Object原型对象上的toString方法才能判断&#xff0c;其他原型对象上的不能判断&#xff0c;如 Array原型对象上的toString方法是判断不了的&#xff0c;因为它重写了toString方法。 要使用Object…

js判断数据类型(全)

js基本数据类型 基本数据类型&#xff1a; String、Number、Boolean、Undefined未定义、null空、symbol表示独一无二的值&#xff08;es6引入的新的原始数据基本类型&#xff09;。 Number&#xff1a;返回的特殊值NaN&#xff0c;表示不是数值&#xff0c;用于表示本来要返回…

判断JS数据类型的五种方法

JavaScript 中常见的几种数据类型&#xff1a; 目录 JavaScript 中常见的几种数据类型&#xff1a; 一、分类 二、判断 1、typeof null既然属于基本数据类型&#xff0c;为什么用typeof返回的是object呢&#xff1f; js小数运算出现的问题(精度丢失) 解决方法一 解决方…

Linux 文件类型及常用命令(2)(cp、mv、cat、more、less、head、tail、chmod、getenforce)

1、命令 cp&#xff1a;拷贝&#xff08;类似于Windows系统的复制&#xff0c;但区别是可以重命名&#xff09; 拷贝文件、目录&#xff08;需要使用 -r 参数&#xff09;&#xff0c;可以重命名。 2、命令 mv&#xff1a;移动或重命名 ①如果是在当前目录下移动&#xff0c…

Linux验证SELinux状态

安全增强型Linux&#xff08;SELinux&#xff09;是一个Linux内核的功能&#xff0c;它提供支持访问控制的安全政策保护机制。记录操作如何验证SELinux&#xff0c;并且避免系统无法启动的问题。 以root权限执行&#xff1a;sudo su - 运行命令getenforce&#xff0c;验证SELi…

Linux 查看 SELinux 的状态

可以运行下面的命令来查看当前服务配置的 SELinux 的状态。 getenforce 上面的输出状态显示了当前 SELinux 的配置状态。 如果上图显示当前的状态。 临时禁用 SELinux 。 使用下面的命令来临时禁用 SELinux。 setenforce 0 Linux 查看 SELinux 的状态 - 系统和容器 - OSSE…

Android Senlinux 基础说明

一、SELinux 三种模式简介 Enforcing&#xff1a;强制模式。代表SELinux在运行中&#xff0c;且已经开始限制domain/type之间的验证关系Permissive&#xff1a;宽容模式。代表SELinux在运行中&#xff0c;不过不会限制domain/type之间的验证关系&#xff0c;即使验证不正确&…

如何关闭防火墙和selinux操作

在每次部署相关软件的时候总是会遇到各种奇奇怪怪的问题&#xff0c;多半是防火墙没有关&#xff0c;或者是selinux没有关 如何关闭防火墙&#xff1a; 那先来看一下防火墙的状态&#xff1a;systemctl status firewalld 如果是下图所示开着的&#xff0c;那就把它给关了&am…

Linux下如何关闭SELinux的图文教程(完整版)

大家好&#xff01; 最近遇到Mysql数据启动报错的问题&#xff0c;于是发现是因为SELinux没有关闭&#xff0c;那么这篇文章就简单的记录SElinux是如何让关闭的。 前言 SELinux(Security-Enhanced Linux) 是美国国家安全局&#xff08;NSA&#xff09;对于强制访问控制的实现…

Android8.x/9.x/10.x user版本关闭selinux以及打开UART控制台输入和关闭内核日志输出功能

1、user版本关闭selinux 仅限于系统调试时使用&#xff0c;量产版本需要将其设置回去成ELINUX_ENFORCING模式。 1.1)背景 C:\Users\zhaojr> adb root C:\Users\zhaojr> adb remount C:\Users\zhaojr> adb shell ac8257:/ # getenforce getenforce Enforcing这个表明…

GeForce Experience 绕过登录与禁止自动更新

本文说明了&#xff0c;如何在未注册Nvidia账户的情况下&#xff0c;绕过GeForce Experience&#xff08;以下简称为GFE&#xff09;账户登录的方法&#xff0c;从而直接使用登陆后才能使用的各种功能。在PC未联网的情况下&#xff0c;此方法依旧能正常绕过登录&#xff0c;直接…