go語言記log:glog剖析

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

log的一個典型應用情境就是實現log分級,比如線上環境不需要記錄DEBUG的log資訊。今天介紹一下glog。先看一個glog的簡單例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//file name: glog.go
package main

import (
"flag"
"github.com/golang/glog"
)

func main() {
flag.Parse() // 1

glog.Info("This is a Info log") // 2
glog.Warning("This is a Warning log")
glog.Error("This is a Error log")

glog.V(1).Infoln("level 1") // 3
glog.V(2).Infoln("level 2")

glog.Flush() // 4
}

如果你之前沒有用過glog,需要使用go get安裝一下,你需要像下面這樣執行這個go程式。上面標註的幾個地方可以先注意一下,等文章讀完就理解了。

1
2
3
$ go get
$ go build glog.go
$ ./glog -log_dir="./"

這時候不出意外的話,會在同級目錄下產生下面幾個類似的log檔案。

1
2
3
glog.kltao-mac.kltao.log.ERROR.20160312-173205.22052
glog.kltao-mac.kltao.log.INFO.20160312-173205.22052
glog.kltao-mac.kltao.log.WARNING.20160312-173205.22052

這就是產生的log檔案,開啟第一個ERROR的log檔案,檔案內容如下。前面4行是檔案響應資訊,最後一行就是上面第14行代碼記錄的log內容。

1
2
3
4
5
Log file created at: 2016/03/12 17:32:05
Running on machine: kltao-mac
Binary: Built with gc go1.4.2 for darwin/amd64
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
E0312 17:32:05.568597 22052 glog.go:15] This is a Error log

這個時候如果你開啟另外兩個INFO和WARNING的log檔案,會發現WARNING記錄檔中除了WARNING資訊還記錄了Error資訊(This is a Error log),而INFO記錄檔中則記錄了所有的log資訊(This is a Info/Warning/Error log)。很容易理解,這些log是有等級的(ERROR>WARNING>INFO),高等級的日誌內容會同時會被記錄到低等級的記錄檔中去。那麼glog提供了一個等級呢?答案是4個,除了上面提出的3個,還有一個FALTAL。
這時候又有一個問題來了,為什麼第3處的日誌資訊沒有記錄下來呢?不急,這個時候如下重新執行一下。就可以在新的INFO記錄檔中找到了對應的資訊了。

1
./glog -log_dir="./" -v=3

對,就是這個-v參數。再說V之前,先說一下glog的命令列解析,對應代碼就是標註的第1處。那麼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
29
30
31
32
// By default, all log statements write to files in a temporary directory.
// This package provides several flags that modify this behavior.
// As a result, flag.Parse must be called before any logging is done.
//
// -logtostderr=false
// Logs are written to standard error instead of to files.
// -alsologtostderr=false
// Logs are written to standard error as well as to files.
// -stderrthreshold=ERROR
// Log events at or above this severity are logged to standard
// error as well as to files.
// -log_dir=""
// Log files will be written to this directory instead of the
// default temporary directory.
//
// Other flags provide aids to debugging.
//
// -log_backtrace_at=""
// When set to a file and line number holding a logging statement,
// such as
// -log_backtrace_at=gopherflakes.go:234
// a stack trace will be written to the Info log whenever execution
// hits that statement. (Unlike with -vmodule, the ".go" must be
// present.)
// -v=0
// Enable V-leveled logging at the specified level.
// -vmodule=""
// The syntax of the argument is a comma-separated list of pattern=N,
// where pattern is a literal file name (minus the ".go" suffix) or
// "glob" pattern and N is a V level. For instance,
// -vmodule=gopher*=3
// sets the V level to 3 in all Go files whose names begin "gopher".

glog.V(1).Infoln("level 1")這行代碼錶示設定的-v參數大於V()裡面的參數才執行後面的Infoln。如果不加-v參數,預設等級為0,所以第三處的代碼沒有執行。具體實現不妨看一下源碼實現,一目瞭然。

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
type Verbose bool

func V(level Level) Verbose {
// This function tries hard to be cheap unless there's work to do.
// The fast path is two atomic loads and compares.

// Here is a cheap but safe test to see if V logging is enabled globally.
if logging.verbosity.get() >= level {
return Verbose(true)
}

// It's off globally but it vmodule may still be set.
// Here is another cheap but safe test to see if vmodule is enabled.
if atomic.LoadInt32(&logging.filterLength) > 0 {
// Now we need a proper lock to use the logging structure. The pcs field
// is shared so we must lock before accessing it. This is fairly expensive,
// but if V logging is enabled we're slow anyway.
logging.mu.Lock()
defer logging.mu.Unlock()
if runtime.Callers(2, logging.pcs[:]) == 0 {
return Verbose(false)
}
v, ok := logging.vmap[logging.pcs[0]]
if !ok {
v = logging.setV(logging.pcs[0])
}
return Verbose(v >= level)
}
return Verbose(false)
}

func (v Verbose) Info(args ...interface{}) {
if v {
logging.print(infoLog, args...)
}
}

func (v Verbose) Infoln(args ...interface{}) {
if v {
logging.println(infoLog, args...)
}
}

func (v Verbose) Infof(format string, args ...interface{}) {
if v {
logging.printf(infoLog, format, args...)
}
}

程式中標註的4個地方,除了第4個地方,其他都說了,Flush的作用清空緩衝區,就是把日誌寫到檔案。golog初始化的時候,起了一個Flush的守護進程,然後定期去執行I/O操作,所以退出的時候需要顯示清除一下緩衝區。glog啟動的初始化代碼如下。

1
2
3
4
func init() {
...
go logging.flushDaemon()
}

上面應該是glog的大部分使用方法了,更詳細的資訊可以參考github.com/golang/glog。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.