[glog]_[C/C++]_[使用glog来记录日志]
2016-12-31 20:51
423 查看
glog 快速使用教程
场景
1.大部分程序由函数组成, 每个函数执行一段设计好的逻辑, 但是大部分的时候有可能出现意料之外的值, 这时候就很想知道这种意料以外的值是如何产生的, 这就需要一个函数调用和参数跟踪, 日志正好发挥作用.2.调试多线程程序时某些函数执行顺序可能出现期望之外的顺序,或者需要知道出问题时线程执行的顺序,而Debug程序并不能同时Debug多个线程的函数调用, 而且会影响线程的竞争导致bug无法重现,这时只能用日志.
3.在客户使用软件时, 经常需要分析用户的使用习惯和行为, 从而根据用户行为习惯来重点推荐产品, 这时候就需要历史日志.
说明
1.glog只支持utf8编码的日志文件.2.glog的严重程度级别只支持4种, INFO, WARNING, ERROR, and FATAL. 也就是LOG(XXX); DLOG用来记录DEBUG模式的日志, 在Release模式下会未定义,不用担心性能问题(#ifndef NDEBUG). 默认情况下会把 ERROR 或 FATAL 级别输出到stderr.
3.条件或偶发性日志, 可允许指定变量满足特定值才输出日志. 比如a>10,每请求10次日志才输出一次,限制输出的前几次. LOG_IF,LOG_EVERY_N,LOG_IF_EVERY_N,LOG_FIRST_N. 如果只需要在Debug模式下输出. DLOG,DLOG_IF,DLOG_EVERY_N.
4.检查宏用来检查期待的条件, 如果不满足条件,就会中断程序.CHECK,CHECK_NE,CHECK_EQ,CHECK_EQ,CHECK_NOTNULL,CHECK_STREQ,CHECK_STRNE,CHECK_STRCASEEQ,CHECK_STRCASENE 等等. 如果不想让程序中断的话, 这些宏很少用.
5.设置标记, 可以通过命令行设置参数, 比如 ./your_application –logtostderr=1, 但是要使用 Google gflags library. 如果没有使用gflags库, 可以使用环境变量设置. GLOG_logtostderr=1, FLAGS_v=1. 或者在代码里设置 FLAGS_*.
6.Raw Logging, 使用头文件
例子
注意, 这个例子只是产生输出, 如果想把日志输出到文件, 那么把 FLAGS_logtostderr=false.// test-log.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" // 使用Windows自带的SEVERITIES定义 #define GLOG_NO_ABBREVIATED_SEVERITIES #include <Windows.h> #include <glog/logging.h> #include <glog/raw_logging.h> static char* ConvertUnicodeToUtf8(const wchar_t* unicode) { if(unicode == NULL) { return strdup("\0"); } int len; len = WideCharToMultiByte(CP_UTF8, 0,unicode, -1, NULL, 0, NULL, NULL); char *szUtf8 = (char*)malloc(len + 1); memset(szUtf8, 0, len + 1); WideCharToMultiByte(CP_UTF8, 0,unicode, -1, szUtf8, len, NULL,NULL); return szUtf8; } void TestLogSeverityLevel() { LOG(INFO) << "TestLogSeverityLevel the INFO text"; DLOG(INFO) << "TestLogSeverityLevel the DEBUG text"; LOG(ERROR) << "TestLogSeverityLevel the ERROR text1"; LOG(WARNING) << "TestLogSeverityLevelthe warning text"; LOG(ERROR) << "TestLogSeverityLevel the ERROR text2"; // DLOG(FATAL) << "DEBUG FATAL"; // 会产生一个abort中断之前先输出到日志 } void TestSettingFlags() { // 日志文件格式 ///tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid> // test-log.exe.APPLE-PC.apple.log.INFO.20161230-155337.2472 // 注意,文件路径编码必须是GB2312,不然不识别以下中文路径,如果文件不是本地编码(ANSI),那么需要转换为ANSI编码. // 设置日志目录,必须是ANSI(中文系统即GB2312)编码,不支持UNICODE // 该目录必须存在,不然生成不了日志文件. FLAGS_logtostderr = true; // 不输出到文件,输出到stderr. FLAGS_log_dir = "E:\\新建文件夹\\"; FLAGS_max_log_size = 20; // 设置最大日志文件大小. } void TestConditionalAndOccasionalLogging() { for(int i = 0; i< 100;++i) { LOG_IF(INFO,i%10 == 0) << "LOG_IF i is " << i; // 每10次输出一次. LOG_EVERY_N(INFO,10) << " LOG_EVERY_N i is " << i << " Got the " << google::COUNTER; // 也是每间隔10次输出 LOG_FIRST_N(INFO, 20) << "LOG_FIRST_N i is " << i << " Got the " << google::COUNTER; // 输出前20个 } } void TestCHECKMacros() { std::string first = "abcd"; std::string second = "AbCd"; CHECK_EQ(first,second); //产生一个中断之前先输出到日志 } int _tmain(int argc, _TCHAR* argv[]) { // Initialize Google's logging library. // glog保存的文件时UTF-8格式编码,所以需要转码需要记录的字符串为UTF-8,转换为utf8. char* argv0 = ConvertUnicodeToUtf8(argv[0]); google::InitGoogleLogging(argv0); TestSettingFlags(); TestLogSeverityLevel(); TestConditionalAndOccasionalLogging(); TestCHECKMacros(); // 日志内容 //Log file created at: 2016/12/30 15:53:37 //Running on machine: APPLE-PC //Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg //I1230 15:53:37.337400 5456 test-log.cpp:35] the same file //google::FlushLogFiles(google::GLOG_ERROR); google::ShutdownGoogleLogging(); return 0; }
输出
I1231 20:33:15.303700 5852 test-log.cpp:31] TestLogSeverityLevel the INFO text I1231 20:33:15.303700 5852 test-log.cpp:32] TestLogSeverityLevel the DEBUG text E1231 20:33:15.303700 5852 test-log.cpp:33] TestLogSeverityLevel the ERROR text 1 W1231 20:33:15.303700 5852 test-log.cpp:34] TestLogSeverityLevelthe warning tex t E1231 20:33:15.303700 5852 test-log.cpp:35] TestLogSeverityLevel the ERROR text 2 I1231 20:33:15.303700 5852 test-log.cpp:57] LOG_IF i is 0 I1231 20:33:15.303700 5852 test-log.cpp:58] LOG_EVERY_N i is 0 Got the 1 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 0 Got the 1 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 1 Got the 2 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 2 Got the 3 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 3 Got the 4 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 4 Got the 5 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 5 Got the 6 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 6 Got the 7 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 7 Got the 8 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 8 Got the 9 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 9 Got the 10 I1231 20:33:15.303700 5852 test-log.cpp:57] LOG_IF i is 10 I1231 20:33:15.303700 5852 test-log.cpp:58] LOG_EVERY_N i is 10 Got the 11 I1231 20:33:15.303700 5852 test-log.cpp:59] LOG_FIRST_N i is 10 Got the 11 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 11 Got the 12 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 12 Got the 13 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 13 Got the 14 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 14 Got the 15 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 15 Got the 16 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 16 Got the 17 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 17 Got the 18 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 18 Got the 19 I1231 20:33:15.319300 5852 test-log.cpp:59] LOG_FIRST_N i is 19 Got the 20 I1231 20:33:15.319300 5852 test-log.cpp:57] LOG_IF i is 20 I1231 20:33:15.319300 5852 test-log.cpp:58] LOG_EVERY_N i is 20 Got the 21 I1231 20:33:15.319300 5852 test-log.cpp:57] LOG_IF i is 30 I1231 20:33:15.319300 5852 test-log.cpp:58] LOG_EVERY_N i is 30 Got the 31 I1231 20:33:15.319300 5852 test-log.cpp:57] LOG_IF i is 40 I1231 20:33:15.319300 5852 test-log.cpp:58] LOG_EVERY_N i is 40 Got the 41 I1231 20:33:15.319300 5852 test-log.cpp:57] LOG_IF i is 50 I1231 20:33:15.319300 5852 test-log.cpp:58] LOG_EVERY_N i is 50 Got the 51 I1231 20:33:15.319300 5852 test-log.cpp:57] LOG_IF i is 60 I1231 20:33:15.319300 5852 test-log.cpp:58] LOG_EVERY_N i is 60 Got the 61 I1231 20:33:15.319300 5852 test-log.cpp:57] LOG_IF i is 70 I1231 20:33:15.319300 5852 test-log.cpp:58] LOG_EVERY_N i is 70 Got the 71 I1231 20:33:15.319300 5852 test-log.cpp:57] LOG_IF i is 80 I1231 20:33:15.319300 5852 test-log.cpp:58] LOG_EVERY_N i is 80 Got the 81 I1231 20:33:15.319300 5852 test-log.cpp:57] LOG_IF i is 90 I1231 20:33:15.319300 5852 test-log.cpp:58] LOG_EVERY_N i is 90 Got the 91 F1231 20:33:15.319300 5852 test-log.cpp:67] Check failed: first == second (abcd vs. AbCd) *** Check failure stack trace: ***
参考
1.源码的doc/glog.html相关文章推荐
- [glog]_[C/C++]_[使用glog来记录日志]
- 使用STL流(stream)来简化C++“线程安全”日志记录
- Caffe中Glog日志记录的使用与安装!
- 使用STL流(stream)来简化C++“线程安全”日志记录
- C++的开源跨平台日志库glog学习研究(二)--宏的使用
- 在C++中使用Apache的Log4cxx记录日志
- C++的开源跨平台日志库glog学习研究(二)--宏的使用
- 在C++中使用Apache的Log4cxx记录日志
- 在C++中使用Apache的Log4cxx记录日志(转帖)
- 使用STL流(stream)来简化C++“线程安全”日志记录
- 在C++中使用Apache的Log4cxx记录日志
- 在C++中使用Apache的Log4cxx记录日志
- 使用log4net组件记录系统日志
- log4j和commons.logging日志记录的使用方法
- [c++]记录Windows程序“应用程序错误”到异常日志
- IIS使用ODBC记录日志
- 网络工程师交换试验手册之二十四:使用syslog记录Cisco设备日志
- iptables学习与研究四(使用LOG记录失败日志)
- 装饰者模式---使用装饰者模式实现带日志记录功能的数据库命令执行类
- 在.Net程序中使用log4net记录日志(示例)-转