golang/glog 是 C++ 版本 google/glog 的 Go 版本实现,基本实现了原生 glog 的日志格式。在 Kuberntes 中,glog 是默认日志库。

glog 的使用与特性

通用功能

glog 将日志级别分为 4 种,分别是:

  • INFO:普通日志;
  • WARNING:告警日志;
  • ERROR:错误日志;
  • FATAL:严重错误日志,打印完日志后程序将会推出(os.Exit()

glog 的使用很简单,可参考下面这个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
"flag" "github.com/golang/glog"
) func main() {
flag.Parse()
defer glog.Flush() glog.Info("This is info message")
glog.Infof("This is info message: %v", 12345)
glog.InfoDepth(1, "This is info message", 12345) glog.Warning("This is warning message")
glog.Warningf("This is warning message: %v", 12345)
glog.WarningDepth(1, "This is warning message", 12345) glog.Error("This is error message")
glog.Errorf("This is error message: %v", 12345)
glog.ErrorDepth(1, "This is error message", 12345) glog.Fatal("This is fatal message")
glog.Fatalf("This is fatal message: %v", 12345)
glog.FatalDepth(1, "This is fatal message", 12345)
}

当我们运行:

1
$ mkdir -p log && go run main.go -log_dir=log -alsologtostderr

以上打印日志将会同时打印在 log/ 目录和标准错误输出中(-alsologtostderr)。

其中在 log/ 中将会产生如下日志文件:

1
2
3
4
5
6
7
8
main.INFO -> main.ut1.test.log.INFO.20180715-130428.27339
main.WARNING -> main.ut1.test.log.WARNING.20180715-130428.27339
main.ERROR -> main.ut1.test.log.ERROR.20180715-130428.27339
main.FATAL -> main.ut1.test.log.FATAL.20180715-130428.27339
main.ut1.test.log.ERROR.20180715-130428.27339
main.ut1.test.log.FATAL.20180715-130428.27339
main.ut1.test.log.INFO.20180715-130428.27339
main.ut1.test.log.WARNING.20180715-130428.27339

其中 main.INFO 这类文件表示的是 INFO 日志对应的符号链接。当单个日志文件达到一定大小时,glog 将会有 rotate 的动作:即关闭已经满量的文件,新建日志文件

vmodule 功能

glog 最常用的就是 V level 的功能,如下所示:

1
2
3
4
5
6
7
8
9
func main() {
flag.Parse()
defer glog.Flush() glog.V(3).Info("LEVEL 3 message") // 使用日志级别 3
glog.V(4).Info("LEVEL 4 message") // 使用日志级别 4
glog.V(5).Info("LEVEL 5 message") // 使用日志级别 5
glog.V(8).Info("LEVEL 8 message") // 使用日志级别 8
}

当我们重新运行:

1
$ go run main.go -log_dir=log -alsologtostderr

将不会看到任何输出,因为日志级别不够,我们通过指定日志级别(-v,log level):

1
$ go run main.go -v=4 -log_dir=log -alsologtostderr

此时,日志级别小于或等于 4 的日志将被打印出来:

1
2
I0715 13:15:41.380611   29471 main.go:13] LEVEL 3 message
I0715 13:15:41.388777 29471 main.go:14] LEVEL 4 message

如果我们想对不同的文件实行不同的日志级别,可以用 vmodule 功能,如下代码:

1
2
3
4
5
6
7
8
9
10
func main() {
flag.Parse()
defer glog.Flush() bar()
glog.V(3).Info("LEVEL 3 message")
glog.V(4).Info("LEVEL 4 message")
glog.V(5).Info("LEVEL 5 message")
glog.V(8).Info("LEVEL 8 message")
}

其中 bar() 的实现在 bar.go

1
2
3
func bar() {
glog.V(4).Info("LEVEL 4: level 4 message in bar.go")
}

当我们执行:

1
$ go run main.go bar.go -v=3 -log_dir=log -alsologtostderr -vmodule=bar=5

对所有文件的日志级别设定为 3 (-v=3),但是对 bar.go (-vmodule 的输入参数省去 .go 后缀,且必须以 -vmodule=recordio=2,file=1,gfs*=3 的语法格式)的日志级别设定为 5,此时会输出:

1
2
I0715 13:20:28.381611   30447 bar.go:6] LEVEL 4: level 4 message in bar.go
I0715 13:20:28.383866 30447 main.go:14] LEVEL 3 message

通过该功能,可以对指定模块采用不同日志级别的输出,可有效提升调试效率。

traceLocation 功能

traceLocation 的命令格式为 -log_backtrace_at=gopherflakes.go:234,当运行到指定代码处时,将把该代码的栈信息打印出来,延续上面的代码,我们运行:

1
$ go run main.go bar.go -v=3 -log_dir=log -alsologtostderr -vmodule=bar=5 -log_backtrace_at=bar.go:6

可见如下输出:

1
2
3
I0715 13:28:17.915837   31920 bar.go:6] LEVEL 4: level 4 message in bar.go
... 打印 backtrace,此处省略 ...
I0715 13:28:17.923715 31920 main.go:14] LEVEL 3 message

日志格式

从上面的例子可以看出,glog 打印的日志基本格式为:

1
<header>] <message>

header 和 message 之间用 ] 分隔。其中 header 的格式为:

1
Lmmdd hh:mm:ss.uuuuuu threadid file:line

这里要注意的是 L,它代表了 glog 原本的日志级别:

1
2
3
4
I -> INFO
W -> WARNING
E -> ERROR
F -> FATAL

后面几个字段分别代表的是时间信息。在 C++ 中,threadid 表示的是线程信息,但在 Go 版本实现中,threadid 是进程 PID,即 os.Getpid() 的调用结果。

这部分详细代码可参考:glog.go 中的 formatHeader() 函数。

glog 的实现

其实,用 Go 实现一个日志库并不困难,其本质就是:在 buffer 中写入格式化的内容并定期刷入文件中。glog 的基本实现逻辑也是如此。

参考

  1. 深入学习 Go 语言函数调用信息
  2. An example of how to use golang/glog

Golang glog使用详解的更多相关文章

  1. Golang Context 包详解

    Golang Context 包详解 0. 引言 在 Go 语言编写的服务器程序中,服务器通常要为每个 HTTP 请求创建一个 goroutine 以并发地处理业务.同时,这个 goroutine 也 ...

  2. 【GoLang】golang context channel 详解

    代码示例: package main import ( "fmt" "time" "golang.org/x/net/context" ) ...

  3. Golang bytes.buffer详解

    原文:https://www.jianshu.com/p/e53083132a25 Buffer 介绍 Buffer 是 bytes 包中的一个 type Buffer struct{…} A buf ...

  4. Golang 并发Groutine详解

    概述 1.并行和并发 并行(parallel):指在同一时刻,有多条指令在多个处理器上同时执行. 并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在 ...

  5. golang context用法详解

    背景 在go服务器中,对于每个请求的request都是在单独的goroutine中进行的,处理一个request也可能设计多个goroutine之间的交互, 使用context可以使开发者方便的在这些 ...

  6. golang中接口详解

    package main import ( "fmt" ) type Sayer interface { say() } type Mover interface { move() ...

  7. Golang入门教程(十三)延迟函数defer详解

    前言 大家都知道go语言的defer功能很强大,对于资源管理非常方便,但是如果没用好,也会有陷阱哦.Go 语言中延迟函数 defer 充当着 try...catch 的重任,使用起来也非常简便,然而在 ...

  8. GoLang基础数据类型--->字典(map)详解

    GoLang基础数据类型--->字典(map)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是 ...

  9. golang格式化输出-fmt包用法详解

    golang格式化输出-fmt包用法详解 注意:我在这里给出golang查询关于包的使用的地址:https://godoc.org    声明: 此片文章并非原创,大多数内容都是来自:https:// ...

随机推荐

  1. 732. My Calendar III (prev)

    Implement a MyCalendarThree class to store your events. A new event can always be added. Your class ...

  2. 代码修改shader Properties uniform变量

    2.4 Shader的数据接口:属性和 uniform变量     如果我们想设定一个特定的值到Shader,即为了在实例化Shader为Material时,可以通过为属性赋值达到创建具体对象的目的, ...

  3. 三、python的基本类型

    一.number 整数 int 浮点数 float 1.type()查看类型 >>> type(1) <class 'int'> >>> type(1. ...

  4. C# Dictionary类型转json方法之一

    using Newtonsoft.Json;//引用命名空间 Dictionary<string, string> Content = new Dictionary<string, ...

  5. [Android]Android四大组件之ContentProvider

    URI简介 URI(Universal Resource Identifier),又被称为"通用资源标志符". URI由许多部分所组成,示例及解说如下: Content URIs介 ...

  6. UVaLive6435(dp)

    要点 题意:两个数据传输数列,每个数列里有若干个数据包并给出发出时间\(t\),每个数据包到达的时间\(T\)是\(t <= T < t + D\),问有多少种到达序列. 将题目转化为第二 ...

  7. 【手撸一个ORM】第四步、Expression(表达式目录树)扩展

    到这里,Orm的基架已经搭起来了,接下来就是激动人心的部分,表达式目录树转Sql语句,SqlDataReader转数据实体等等,但是在这之前,我们需要扩展下表达式目录树的方法,以方便后面的相关操作. ...

  8. Ocelot API

    Ocelot API网关的实现剖析   在微软Tech Summit 2017 大会上和大家分享了一门课程<.NET Core 在腾讯财付通的企业级应用开发实践>,其中重点是基于ASP.N ...

  9. mysql issue:

    ####0 https://yq.aliyun.com/ziliao/53466 首先,很荣幸你找到了这篇文章... 如果你忘记了mysql的密码不妨试试以下这个方法. 1.打开my.cnf  代码如 ...

  10. JavasJavaScript笔试题

    这几天参加了好多场宣讲会,记录一下遇到的编程题还有平时练习遇到的(如果有更好的方法欢迎提出,本人也是菜鸟一枚): 1.数组查重,并返回出重复次数最多的项并记录重复次数: function chacho ...