标签归档:glog

glog FATAL日志写多次的问题

【背景】
LOG(FATAL)能够使代码更加简洁,在项目中用得比较多。但实际真正触发的时候,看日志总感觉没有写进去。去日志目录观察,实际上是写了两份日志,而当前的日志软连接链到了空日志文件上。这在日志目录下日志文件比较多时,查看上一次挂掉的日志非常不方便。
glog原始情况

【研究】
实际上阅读glog代码发现SendToLog这个函数在打印完所有日志之后,针对FATAL级别的日志,又重新写了一次,而且时间戳是0即(19700101-080000)。

 【解决】
注释掉该段代码搞定。
glog-after-fix

glog崩溃时的堆栈信息添加行号

glog提供了接口可以在程序崩溃时打桩,这里已经能打印基本的堆栈信息,但是没有对应的行号。通过大量的库去解析非常麻烦,而且崩溃时程序一般就要退出了,所以也不在意性能了,所以用一些偏门的方法,比如addr2line去分析出行号。

 

glog的C语言风格日志

c++的流输入输出用久了毛病就出来了,参数多的时候打印代码写起来就忒别扭,不能一气呵成的编排好格式。

1. 然后就对c++日志接口做了一层简单的封装

2. 再然后我发现自己搞错了, glog原生就有自己的C风格日志输出,只不过放在raw_logging.h里头。

细看glog

【基本状况】
1. glog只维护四种级别的日志(log_serverity.h定义 GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3)
2. 默认文件名样式: “进程名.机器名.用户名.log.日志级别.日期-时间.进程名”
3. glog支持条件日志,特定场景很有用
4. glog支持模块日志(-vmodule=xxx=yy),非常有用,可以限定到那个文件的那个级别输出
5. 程序core时输出堆栈上下文,这个调试非常有用
6. 没有初始化时日志统统打印到stderr终端
7. 充分利用临时对象,锁是对象销毁时自动解锁,LogMessage是对象析构时自动flush触发真正的写日志

【类】
存放在头文件中,方便外部使用和扩展
– LogMessage 管理写日志信息,glog的基本语法LOG()就是对他的宏定义{内部友员包含LogDestination}
– LogSink 用于添加新的写入后端,glog扩展性的体现
– LogStream 是对std::ostrstream的扩展, 使用其<<符号

– Logger 真正写日志的类(可以在LogDestination中设置)
– LogFileObject 管理日志文件命名/轮转/写入等 LogDestination 日志的后端(LogToSinks,LogToAllLogfiles,MaybeLogToStderr,MaybeLogToLogfile),内部友员包含LogMessage

【LOG(INFO)的演变】
LOG(INFO)
->
#define LOG(severity) COMPACT_GOOGLE_LOG_ ## severity.stream()
->
#define COMPACT_GOOGLE_LOG_INFO @ac_google_namespace@::LogMessage(__FILE, __LINE__)
->
Init(file, line, GLOG_INFO, &LogMessage::SendToLog)
->
LogMessage::~LogMessage()

【特化事例】

  1. 增加新后端
  2. 继承google::LogSink,最重要的实现这个send接口,然后用google::AddLogSink(sink子类)将sink添加到glog后端,自此LOG(INFO)写日志时就会同时写到新添加的后端。

  3. 写日志到特定的后端
  4. 由于某些需要,你可能并不希望将日志写到所有后端(这里会写到所有后端,包括Files,stderr,Email, Sinks)
    a) 仅仅写日志到sink
    glog已经有这个宏了,LOG_TO_SINK_BUT_NOT_TO_LOGFILE(sink, severity)
    b) 仅仅写日志到文件
    目前glog没有相应的宏,只得修改源码,在不修改现有接口和功能的原则,新增代码:
    – 给LogMessage添加一个SendToFile()的成员函数()
    – 借用现有的构造函数LogMesage构造宏

  5. 改变写日志的方式
  6. 以下是glog的官方Issue 54中commitor给出的一种在cgi中写日志的方法。通过定义自己的Logger,然后将不同级别的执行流绑定到自己的Logger类上就可以控制写入的形态。

  7. 崩溃时写日志
  8. 程序崩溃时追加上下文堆栈信息到日志文件(因为程序崩溃时需要根据core文件去查堆栈信息,有时候core由于某些原因不会生成)