glog使用教程

xiaoxiao2021-02-27  309

glog

glog是一个轻量、稳定、开源的日志系统,详细见上一篇文章所述.这里主要介绍glog的使用.

glog获取和编译

获取glog工程 git clone https://github.com/google/glog.git编译 我这里使用编译工具是”Visual Studio2015”,打开”google-glog.sln”工程,编译会报如下错误: D:\src\test\glog\src\windows\port.h(116): error C2375: 'snprintf': redefinition; different linkage ...

snprintf重复定义问题,其中一种解决办法:

--- a/src/windows/port.h +++ b/src/windows/port.h @@ -111,6 +111,7 @@ enum { STDIN_FILENO = 0, STDOUT_FILENO = 1, STDERR_FILENO = 2 }; * because they don't always NUL-terminate. :-( We also can't use the * name vsnprintf, since windows defines that (but not snprintf (!)). */ +#define HAVE_SNPRINTF #ifndef HAVE_SNPRINTF

编译成功,生成动态库(libglog.dll,libglog.lib),和静态库(libglog_static.lib).接下来以动态库的方式说明glog的使用.

glog使用

添加glog模块到工程 头文件 设置VS2015工程头文件路径:

代码添加:

//为了防止windows.h头文件中的ERROR与glog的ERROR重定义问题.这个宏必须在包含logging.h之前定义! #define GLOG_NO_ABBREVIATED_SEVERITIES #include <glog/logging.h> 添加lib 设置VS2015工程lib路径:

添加代码:

//import lib #pragma comment(lib,"libglog.lib") 添加dll 将前面编译好的”libglog.dll”放到你的运行程序的同级目录下.

LOG

输出你的第一条LOG信息:

//programe name:"HelenXR_glog_program" google::InitGoogleLogging("HelenXR_glog_program"); LOG(INFO) << "google log first info level message!"; //...... DoSomething //Shutdown google's logging library. google::ShutdownGoogleLogging();

此时如果你是的工程时控制台程序,你会发现”google log first info level message!”这句信息并没有输出到控制台中,它们去哪了?别急,这时候你要保持冷静!冷静!冷静! 如果没有设置日志存放的文件夹(下面我们会介绍如何保存到指定文件夹),它们会被存放到指定的路径(windows平台上会默认存放到$(LOCALAPPDATA)的Temp文件夹下,如:C:\Users\dell\AppData\Local\Temp,这个路径中的”dell”是计算机当前的用户名),你可以找到以特定格式命名的文件,格式为:

/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>

例如,我这里运行的是”HelenXR_glog_program.PC-2016-0510-9.dell.log.INFO.20170426-113842.14508”(这个文件名看起来很完整,实际使用还是不方便,花点时间可以修改,这里是我之前做的一个尝试,如果你有兴趣可以做的更好),打开这个文件我们可以看到如下信息:

Log file created at: 2017/04/26 11:38:42 Running on machine: PC-2016-0510-9 Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg I0426 11:38:42.172986 14132 glog.cpp:20] google log first info level message!

上面介绍了日志输出的格式和我们输出的日志信息”google log first info level message!”. glog拥有的4个日志等级:INFO,WARNING,ERROR,FATAL分别对应0,1,2,3.数值越大严重性越高,严重性高的日志不但会保存到自己的日志文件中,还会同时保存到所有比它严重性更低的日志文件中.例如:ERROR信息会被同时打印到INFO,WARNING,ERROR日志文件中,测试代码:

LOG(INFO) << "google log first info level message!"; LOG(WARNING) << "google log first warning level message!"; LOG(ERROR) << "google log first error level message!";

测试结果:

//HelenXR_glog_program.PC-2016-0510-9.dell.log.INFO.20170426-115025.8608 ...(省略开头无关信息) I0426 11:50:25.476213 9092 glog.cpp:20] google log first info level message! W0426 11:50:25.477213 9092 glog.cpp:21] google log first warning level message! E0426 11:50:25.477213 9092 glog.cpp:22] google log first error level message! //HelenXR_glog_program.PC-2016-0510-9.dell.log.WARNING.20170426-115025.8608 ...(省略开头无关信息) W0426 11:50:25.477213 9092 glog.cpp:21] google log first warning level message! E0426 11:50:25.477213 9092 glog.cpp:22] google log first error level message! //HelenXR_glog_program.PC-2016-0510-9.dell.log.ERROR.20170426-115025.8608 ...(省略开头无关信息) E0426 11:50:25.477213 9092 glog.cpp:22] google log first error level message!

同时你注意下控制台的日志信息:

日志信息默认是写入对应的文件中的,这里console里打印出了ERROR等级的日志信息, 这是因为默认情况(stderrthreshold默认为2)下,ERROR和FATAL等级的信息会同时被输出到stderr上,当然你可以通过修改stderrthreshold值来改变.

常用FLAGS

你还可以通过在程序中修改全局变量FLAGS_*来配置.这些FLAG_*标识,你可以在”glog\logging.h”文件中查阅. 这里说一下比较常用的一个标志:FLAGS_log_dir,这个标志用来指定日志保存的路径,需要在”InitGoogleLogging”执行之前修改,代码修改:

//注意指定的路径,必须手动存在,你可以在运行前先创建好,否则生成不了日志文件,路径'\'要转义. FLAGS_log_dir = "D:\\helenxr_glog_log_dir"; //programe name:"HelenXR_glog_program" google::InitGoogleLogging("HelenXR_glog_program"); LOG(INFO) << "google log first info level message!"; LOG(WARNING) << "google log first warning level message!"; LOG(ERROR) << "google log first error level message!";

结果:

到这里Glog的基本日志输出功能已经完成.(文件名和文件路径看起来是不是很不爽?glog有源码可以修改,你可以修改到你满意的情况:-)),接下来的是glog的一些高级功能,这些功能前一篇文章有说明了,下面主要是代码演示.

条件型LOG

条件型LOG包括:LOG_IF,LOG_EVERY_N,LOG_IF_EVERY_N,LOG_FIRST_N等. 代码如下:

//注意FLAGS_log_dir指定的路径,必须手动先创建好,否则生成不了日志文件,另外路径'\'要记得转义. FLAGS_log_dir = "D:\\helenxr_glog_log_dir"; //programe name:"HelenXR_glog_program" google::InitGoogleLogging("HelenXR_glog_program"); //LOG(INFO) << "google log first info level message!"; //LOG(WARNING) << "google log first warning level message!"; //LOG(ERROR) << "google log first error level message!"; //Conditional logging test int test_number = 5; //LOG_IF:条件满足时执行打印. LOG_IF(INFO, test_number > 5) << "LOG_IF:test_number > 5";//no log this message LOG_IF(INFO, test_number == 5) << "LOG_IF:test_number == 5";//log this message //LOG_EVERY_N:此代码每执行过N此后,打印一次,注:第一次也会打印. int loop_count = 0; while (loop_count++ < 50 - 1) { LOG_EVERY_N(INFO,10) << "LOG_EVERY_N:[" << loop_count << "]:"<<"loop in " << google::COUNTER << "th times."; } //LOG_IF_EVERY_N:条件满足情况下每N次,打印一次.注:第一次满足条件也会打印. loop_count = 0; while (loop_count++ < 50 - 1) { LOG_IF_EVERY_N(INFO, (loop_count % 2 == 0),10) << "LOG_IF_EVERY_N:[" << loop_count << "]:" << "loop in " << google::COUNTER << "th times."; } //LOG_FIRST_N:此代码执行的前N此都打印,超过N次后不打印. loop_count = 0; while (loop_count++ < 50 - 1) { LOG_FIRST_N(INFO,10) << "LOG_FIRST_N:[" << loop_count << "]:" << "loop in " << google::COUNTER << "th times."; } google::ShutdownGoogleLogging();

输出日志信息:

Log file created at: 2017/04/26 17:59:13 Running on machine: PC-2016-0510-9 Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg I0426 17:59:13.759878 3016 glog.cpp:30] LOG_IF:test_number == 5 I0426 17:59:13.759878 3016 glog.cpp:34] LOG_EVERY_N:[1]:loop in 1th times. I0426 17:59:13.759878 3016 glog.cpp:34] LOG_EVERY_N:[11]:loop in 11th times. I0426 17:59:13.759878 3016 glog.cpp:34] LOG_EVERY_N:[21]:loop in 21th times. I0426 17:59:13.759878 3016 glog.cpp:34] LOG_EVERY_N:[31]:loop in 31th times. I0426 17:59:13.759878 3016 glog.cpp:34] LOG_EVERY_N:[41]:loop in 41th times. I0426 17:59:13.759878 3016 glog.cpp:39] LOG_IF_EVERY_N:[2]:loop in 2th times. I0426 17:59:13.759878 3016 glog.cpp:39] LOG_IF_EVERY_N:[22]:loop in 22th times. I0426 17:59:13.759878 3016 glog.cpp:39] LOG_IF_EVERY_N:[42]:loop in 42th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[1]:loop in 1th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[2]:loop in 2th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[3]:loop in 3th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[4]:loop in 4th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[5]:loop in 5th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[6]:loop in 6th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[7]:loop in 7th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[8]:loop in 8th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[9]:loop in 9th times. I0426 17:59:13.759878 3016 glog.cpp:44] LOG_FIRST_N:[10]:loop in 10th times.

调试模式支持

glog提供了一些调试模式时输出,正常模式下不输出的宏,如DLOG,DLOG_IF,DLOG_EVERY_N等.这些宏只有在debug模式下才会输出日志,正常模式下不会输出日志,也不会拖慢应用程序的速度.

//Debug Mode support test //如果你工程为Debug模式,下面信息会输出,如果是release模式,下面信息不会输出. DLOG(INFO) << "DLOG:Debug Mode Message!";

Verbose

glog提供VLOG宏来提供自定义打印等级的功能.

//verbose logging test //你可以通过命令行"--v=n",来控制VLOG的输出,VLOG(x),x<=n的情况,VLOG会输出,否则不输出.v默认为0,所以默认情况下VLOG(-1),VLOG(0)能够输出. VLOG(-1) << "VLOG(-1) message."; VLOG(0) << "VLOG(0) message."; VLOG(1) << "VLOG(1) message."; VLOG(2) << "VLOG(2) message."; VLOG(3) << "VLOG(3) message.";

输出的日志信息:

......(省略无关部分) I0426 18:35:52.879662 15440 glog.cpp:57] VLOG(-1) message. I0426 18:35:52.879662 15440 glog.cpp:58] VLOG(0) message.

还有VLOG_XXX等宏,来实现不同的功能,详见”glog\logging.h”.

CHECK宏

CHECK宏的目标是让异常情况尽早被检测到,它的特点就是当所检测条件不满足时,应用程序会中止(类似C语言的assert),同时会以最高等级FATAL写入日志中.

//CHECK macros test test_number = 1; CHECK(test_number == 2) << " but test_number != 2";

上面的代码,会触发你的应用程序中止,并记录到日志中,FATAL日志信息如下:

Log file created at: 2017/04/26 18:20:24 Running on machine: PC-2016-0510-9 Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg F0426 18:20:24.066536 11560 glog.cpp:53] Check failed: test_number == 2 but test_number != 2

还有很多CHECK_XXX宏可以使用,详细见”glog\logging.h”文件.

转载请注明原文地址: https://www.6miu.com/read-11789.html

最新回复(0)