日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go标准库日志打印,以及同时输出到控制台和文件

發布時間:2024/1/1 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go标准库日志打印,以及同时输出到控制台和文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

打印

在使用go寫一些小程序時,我們沒必要引入額外的包,直接使用fmt標準包打印即可:

import "fmt"func main() {fmt.Println("line1")fmt.Print("line2")fmt.Printf("line%d \n", 3)str1 := fmt.Sprintln("hello", 3)str2 := fmt.Sprint("hello ", 1, " 2")str3 := fmt.Sprintf("hello %d", 1)fmt.Print(str1, str2, str3) } line1 line2line3 hello 3 hello 1 2hello 1

那么,有些場景下,我們希望能同時打印到日志文件中要怎么辦呢?

log包

標準庫提供了log組件,用法和fmt一致,有3種方式:

import “log"func main() {log.Println("line1")log.Print("line2")log.Printf("line%d \n", 3) }

和fmt的區別就是多了時間:

2021/08/25 17:23:47 line1 2021/08/25 17:23:47 line2 2021/08/25 17:23:47 line3

我們通過SetFlag函數,可以設置打印的格式:

// For example, flags Ldate | Ltime (or LstdFlags) produce, // 2009/01/23 01:23:23 message // while flags Ldate | Ltime | Lmicroseconds | Llongfile produce, // 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: message const (Ldate = 1 << iota // the date in the local time zone: 2009/01/23Ltime // the time in the local time zone: 01:23:23Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.Llongfile // full file name and line number: /a/b/c/d.go:23Lshortfile // final file name element and line number: d.go:23. overrides LlongfileLUTC // if Ldate or Ltime is set, use UTC rather than the local time zoneLmsgprefix // move the "prefix" from the beginning of the line to before the messageLstdFlags = Ldate | Ltime // initial values for the standard logger )

比如,我們只需要時間和文件名:

import “log"func main() {log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)log.Println("line1")log.Print("line2")log.Printf("line%d \n", 3) }

此時,再次運行,則會打印文件和行號:

2021/08/25 17:27:56 mod_unread_redis.go:32: line1 2021/08/25 17:27:56 mod_unread_redis.go:33: line2 2021/08/25 17:27:56 mod_unread_redis.go:34: line3

如何輸出日志到文件?

log包使用非常簡單,默認情況下,只會輸出到控制臺。

我們可以使用SetOutput改變輸出流,比如輸出到文件。

先來看一下函數原型,其接收一個io.Writer接口:

// SetOutput sets the output destination for the standard logger. func SetOutput(w io.Writer) {// ... }

那么,我們就可以創建一個文件流設置一下就行了。

// 創建、追加、讀寫,777,所有權限 f, err := os.OpenFile("log.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm) if err != nil {return } defer func() {f.Close() }()log.SetOutput(f)

此時,在運行,我們發現日志會輸出到文件,但是控制臺沒有任何東西輸出了。

如何同時輸出到控制臺和文件?

標準庫io包中,有一個MultiWriter,可以把文件流和控制臺標準輸出流整合到一個io.Writer上,其實現上就是一個數組,在執行寫操作時,遍歷數組:

// MultiWriter creates a writer that duplicates its writes to all the // provided writers, similar to the Unix tee(1) command. // // Each write is written to each listed writer, one at a time. // If a listed writer returns an error, that overall write operation // stops and returns the error; it does not continue down the list. func MultiWriter(writers ...Writer) Writer {allWriters := make([]Writer, 0, len(writers))for _, w := range writers {if mw, ok := w.(*multiWriter); ok {allWriters = append(allWriters, mw.writers...)} else {allWriters = append(allWriters, w)}}return &multiWriter{allWriters} }// 重寫io.Writer的Write函數函數,本質上就是遍歷數組,比較巧妙 func (t *multiWriter) Write(p []byte) (n int, err error) {for _, w := range t.writers {n, err = w.Write(p)if err != nil {return}if n != len(p) {err = ErrShortWritereturn}}return len(p), nil }

使用方式如下:

func main() {f, err := os.OpenFile("log.log", os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)if err != nil {return}defer func() {f.Close()}()// 組合一下即可,os.Stdout代表標準輸出流multiWriter := io.MultiWriter(os.Stdout, f)log.SetOutput(multiWriter)log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)log.Println("line1")log.Print("line2")log.Printf("line%d \n", 3) }

此時,再運行,則會同時輸出到控制臺和文件中。

2021/08/25 17:38:02 mod_unread_redis.go:42: line1 2021/08/25 17:38:02 mod_unread_redis.go:43: line2 2021/08/25 17:38:02 mod_unread_redis.go:44: line3


最后更新時間:2022-04-21

總結

以上是生活随笔為你收集整理的Go标准库日志打印,以及同时输出到控制台和文件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。