網頁

2022/5/28

Golang log Logger日誌工具簡介

Go自帶log日誌工具,在標準函式庫的log package。


Go logLogger物件可將日誌訊息輸出到指定的io.Writer位置,例如標準輸出串流(stdout)或檔案。Logger是執行緒安全的所以可用在多個goroutine。

Go log並沒有日誌等級分層(log levels),所以沒有一般日誌工具(例如Java的log4j2)常見的ERRORINFODEBUG。也沒有依時間或檔案大小自動建立log檔的log rotation功能。如需要這些功能需要利用第三方函式庫(e.g. logruszap)或自行實作。



log函式

log提供以下函式可直接以內建的“標準”Logger輸出日誌,主要分為PrintPanicFatal三種:Print即一般的日誌輸出;PanicPrint後呼叫panic()FatalPrint後呼叫os.Exit(1)ln結尾以fmt.Println()後加新行輸出;f結尾以fmt.Printf()格式化字串輸出。

  • log.Print()
  • log.Println()
  • log.Printf()
  • log.Panic()
  • log.Panicln()
  • log.Panicf()
  • log.Fatal()
  • log.Fatalln()
  • log.Fatalf()

main.go

package main

import (
    "log"
)

func main() {
    log.Print("hello")
    log.Println("world")
    log.Printf("data=%v", []int{1, 2, 3})

    log.Panic("panic!!")
}

執行輸出以下,每條印出的日誌訊息前都加上日期間格式2009/01/23 01:23:23

2022/05/28 11:10:25 hello
2022/05/28 11:10:25 world
2022/05/28 11:10:25 data=[1 2 3]
2022/05/28 11:10:25 panic!!
panic: panic!!

goroutine 1 [running]:
log.Panic({0xc0000bff60?, 0x3?, 0xc0000bff60?})
        /usr/local/Cellar/go/1.18/libexec/src/log/log.go:385 +0x65
main.main()
        /../main.go:12 +0x10d
exit status 2

輸出訊息若結尾沒新行(newline)則log會自動加上。所以上面用log.Print()印出的訊息仍會換行。


標準Logger

呼叫log.Default()可取得標準Logger,所以下面執行效果相當於上面用log函式以標準Logger輸出:

main.go

package main

import (
    "log"
)

func main() {
    logger := log.Default() // 取得標準Logger
    logger.Print("hello")
    logger.Println("world")
    logger.Printf("data=%v", []int{1, 2, 3})

    logger.Panic("panic!!")
}

建立Logger

除了標準Logger也可使用log.New(out io.Writer, prefix string, flag int)建立新的Logger,其接收三個參數:

  1. out io.Writer - 設定日誌的輸出位置,例如檔案或標準輸出。
  2. prefix string - 設定日誌訊息前要加的前綴文字。
  3. flag int - 設定日誌輸出參數,例如加上時間日期或檔案路徑等。參數定義在log的常數

例如下面建立一個與標準Logger相同的Logger,以標準錯誤輸出串流(stderr)、無前綴、參數LdateLtime為輸出訊息前加上本地日期時間格式2009/01/23 01:23:23

main.go

package main

import (
    "log"
    "os"
)

func main() {
    logger := log.New(os.Stderr, "", log.Ldate|log.Ltime)
    logger.Print("hello")
    logger.Println("world")
    logger.Printf("data=%v", []int{1, 2, 3})
}

執行印出如下:

2022/05/28 12:25:43 hello
2022/05/28 12:25:43 world
2022/05/28 12:25:43 data=[1 2 3]


輸出到log檔

若要把日誌訊息輸出到檔案,則參數out可改為可讀寫的File。例如下面把日誌輸出到main.go目錄的golog.log

main.go

package main

import (
    "log"
    "os"
)

func main() {
    // open file "golog.log" with read-write permission.
    // create a new file if none exists else append data to the file when writing. 
    f, err := os.OpenFile("golog.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
    if err != nil {
        log.Fatalf("open file error=%v", err)
    }
    defer f.Close()

    logger := log.New(f, "", log.Ldate|log.Ltime)
    logger.Print("hello")
    logger.Println("world")
    logger.Printf("data=%v", []int{1, 2, 3})
}

Default Logger可用Logger.SetOutput(w io.Writer)設定輸出。

main.go

package main

import (
    "log"
    "os"
)

func main() {
    f, err := os.OpenFile("golog.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
    if err != nil {
        log.Fatalf("open file error=%v", err)
    }
    defer f.Close()

    logger := log.Default() // Default Logger
    logger.SetOutput(f)
    logger.Print("hello")
    logger.Println("world")
    logger.Printf("data=%v", []int{1, 2, 3})
}

執行後在main.go新增一個golog.log內容如下:

golog.log

2022/05/28 12:42:29 hello
2022/05/28 12:42:29 world
2022/05/28 12:42:29 data=[1 2 3]


沒有留言:

張貼留言