[glog]_[C/C++]_[使用glog来记录日志]
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来记录日志]的更多相关文章
- Spring_MVC_教程_快速入门_深入分析
Spring MVC 教程,快速入门,深入分析 博客分类: SPRING Spring MVC 教程快速入门 资源下载: Spring_MVC_教程_快速入门_深入分析V1.1.pdf Spring ...
- 基于samba实现win7与linux之间共享文件_阳仔_新浪博客
基于samba实现win7与linux之间共享文件_阳仔_新浪博客 然后启动samba执行如下指令: /dev/init.d/smb start 至此完成全部配置.
- 浅谈 Underscore.js 中 _.throttle 和 _.debounce 的差异
Underscore.js是一个很精干的库,压缩后只有5.2KB.它提供了几十种函数式编程的方法,弥补了标准库的不足,大大方便了JavaScript的编程. 本文仅探讨Underscore.js的两个 ...
- CLOSE-UP FORMALWEAR_意大利进口_2015秋冬_男装发布会_西装图片系列_男装西装设计资料_WeArTrends时尚资讯网_国内最专业的服装设计资讯网站
CLOSE-UP FORMALWEAR_意大利进口_2015秋冬_男装发布会_西装图片系列_男装西装设计资料_WeArTrends时尚资讯网_国内最专业的服装设计资讯网站 CLOSE-UP FORMA ...
- 聚焦设计交易与商业落地 DANG·DHUB设计师平台上线【图】_品牌资讯_服饰_太平洋时尚网
聚焦设计交易与商业落地 DANG·DHUB设计师平台上线[图]_品牌资讯_服饰_太平洋时尚网 聚焦设计交易与商业落地 DANG·DHUB设计师平台上线
- 联系我们_你我想法_【有男度】UNANDU 100%进口 全球设计师品牌精汇 男装_男装搭配_时尚男装_品牌男装_男装搭配技巧_男装网站
联系我们_你我想法_[有男度]UNANDU 100%进口 全球设计师品牌精汇 男装_男装搭配_时尚男装_品牌男装_男装搭配技巧_男装网站 联系我们 2012-02-17 国内北京公司总部 邮编 ...
- Payssion,海外本地支付_海外本地收款_小语种本地支付_外贸收款_外贸网店收款_欧洲本地支付_俄罗斯本地支付_巴西支付_跨境支付_PAYSSION,让跨境支付更轻松!
Payssion,海外本地支付_海外本地收款_小语种本地支付_外贸收款_外贸网店收款_欧洲本地支付_俄罗斯本地支付_巴西支付_跨境支付_PAYSSION,让跨境支付更轻松! 首页 / 关于 ...
- 北京西服定做_衬衫定制_关于我们_Dimoon TLR.
北京西服定做_衬衫定制_关于我们_Dimoon TLR.
- MUD江湖_MUD文字游戏_MUD五指_武林群侠_北侠_夺宝江湖_书剑_文字江湖游戏_MUD游戏下载
MUD江湖_MUD文字游戏_MUD五指_武林群侠_北侠_夺宝江湖_书剑_文字江湖游戏_MUD游戏下载 武侠类手机文字游戏,经典再现高度自由玩法宠物 自制装备 师徒自立门派 自造武功欢迎来玩 Q群 1 ...
- 轻奢请向历史SAY NO_重青网_重庆青年报_重庆青年报电子版_重庆青年报网站_重庆青年报官方网站
轻奢请向历史SAY NO_重青网_重庆青年报_重庆青年报电子版_重庆青年报网站_重庆青年报官方网站 轻奢请向历史SAY NO 经济学家George Taylor在他著名的"裙摆指数" ...
随机推荐
- microsoft azure 映像发布前的检查清单
在发布映像提交到 Azure 镜像市场之前,请确保以下检查单全部通过: 产品映像要求 产品映像必须满足如下要求: 适用于生产环境,Azure 镜像市场原则上不接受测试版本产品上架 映像为自包含映像,所 ...
- Entity Framework工具POCO Code First Generator的使用
在使用Entity Framework过程中,有时需要借助工具生成Code First的代码,而Entity Framework Reverse POCO Code First Generator是一 ...
- 用tableView实现的一种加载数据的布局
用tableView实现的一种加载数据的布局 此博文是应朋友之邀解决他的业务逻辑问题 效果: 素材: 源码: ImageCell.h 与 ImageCell.m // // ImageCell.h / ...
- UIButton的resizableImageWithCapInsets使用解析
UIButton的resizableImageWithCapInsets使用解析 效果: 使用的源文件: 源码: // // ViewController.m // SpecialButton // ...
- swift版的枚举变量
swift版的枚举变量 swift的枚举类型跟普通的类是极为类似的,使用的时候,请不要以为他是一个常量,以下是测试用源码 // // ViewController.swift // SwiftEnum ...
- Hadoop HBase概念学习系列之列、列簇(十二)
列在列簇中依照字典排序.例如,列簇是基础信息或公司域名或水果类.列是基础信息:面貌.基础信息:年龄.公司域名:org.公司域名:edu.水果类:苹果.水果类:香蕉. 列 = 列簇:列修饰符 ...
- Z :彻底了解指针数组,数组指针以及函数指针 [复
原创 :彻底了解指针数组,数组指针以及函数指针 [复制链接] 00 roking 白手起家 帖子 60 主题 16 精华 0 可用积分 74 专家积分 0 在线时间 0 小时 注册时间 2003-10 ...
- Flex布局及其应用
什么是弹性盒子? 弹性盒子是 CSS3 的一种新的布局模式.相对于传统的依赖于display+position+float的布局方式,弹性盒子更加以有效的方式来对一个容器中的子元素进行排列.对齐和分配 ...
- springmvc入门之HelloWorld篇
springmvc是一个基于spring的mvc框架,各种优点啥的用过就知道了.下面开始讲HelloWorldController的实现. 1.开发环境搭建<导jar包+配置文件> 1.1 ...
- BZOJ1188:[HNOI2007]分裂游戏(博弈论)
Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏.该游戏的规则试:共有n个瓶子,标号为0,1,2.....n-1,第i个瓶子中装有p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择3个 ...