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. spring eureka 启动过程

    spring-eureka 在springCloud是类似于 zookeeper的存在,主要负责服务的注册发现. 1   由于是Servlet应用,所以Eureka需要通过servlet的相关监听器  ...

  2. 洛谷P2854 [USACO06DEC]牛的过山车Cow Roller Coaster

    P2854 [USACO06DEC]牛的过山车Cow Roller Coaster 题目描述 The cows are building a roller coaster! They want you ...

  3. 洛谷P1549 棋盘问题(2)

    P1549 棋盘问题(2) 题目描述 在N*N的棋盘上(1≤N≤10),填入1,2,…,N*N共N*N个数,使得任意两个相邻的数之和为素数. 例如:当N=2时,有: 其相邻数的和为素数的有: 1+2, ...

  4. IT兄弟连 JavaWeb教程 经典案例

    案例需求:编写一个jsp servlet程序,在login.jsp发起login.do登录请求,当输入的用户名是abc密码是123时,则判断是登录成功,其它暂时认为是登录失败.当用户登录成功时,将用户 ...

  5. tableview中用动画效果改变cell的高度

    我们要的效果大概就是如下效果: 当我们选择一个cell的时候,我们就要改变它的高度,并且以动画的形式. 我们该如何实现这个效果呢?我们主要需要使用以下这两个方法: - (CGFloat)tableVi ...

  6. linux 之基本命令学习总结

    前言:从今天开始写这系列linux博客了(是学习刘遄老师的<linux就该这么学>),视频学习的资源可以在b站上找到:https://www.bilibili.com/video/av45 ...

  7. docker安装及概述

    相关快捷键 退出:Ctrl-D or exit detach:Ctrl-P + Ctrl-Q Docker 核心技术 1.Namespace — 实现Container的进程.网络.消息.文件系统和主 ...

  8. 微信小程序请求openid错误码40163

    通过wx.login({})方法获取到的code只能使用一次,如果需要在哎服务器端再次请求获取openid来进行校验,需要再次通过wx.login({})方法获取code 否则会报错误代码40163, ...

  9. IOS 转场动画二和透明控制器视图

    一.透明视图控制器 WJListMenuViewController *VC = [[WJListMenuViewController alloc]init]; VC.modalPresentatio ...

  10. [Android]Android之四种常见布局

    一个丰富的界面总是要由很多个控件组成的,那我们如何才能让各个控件都有条不紊地 摆放在界面上,而不是乱糟糟的呢?这就需要借助布局来实现了.布局是一种可用于放置很 多控件的容器,它可以按照一定的规律调整内 ...