zoukankan      html  css  js  c++  java
  • Golang glog使用详解

    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
  • 相关阅读:
    一名菜鸟程序员的跳槽经历以及其所感所想(二)
    C#调用WebService
    IIS Error:404.2 The page you are requesting cannot be served because of the ISAPI and CGI Restriction list settings on the Web server
    C#操作XML简析系列(1)之增删修改查
    The web server process that was being debugged has been terminated by Internet Information Services (IIS).
    一名菜鸟程序员的跳槽经历以及其所感所想(一)
    访问WebService出现IIS错误:The request failed with HTTP status 401: Unauthorized
    Windows2008服务器搭建Apollo_MQTT服务
    [ObjC笔记] "self = [super init]"的解释与潜藏bug
    [LBS]查询离某个经纬附近的数据SQL语句
  • 原文地址:https://www.cnblogs.com/sunsky303/p/11081165.html
Copyright © 2011-2022 走看看