欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang?日志庫ZAP[uber-go?zap]示例詳解

 更新時間:2024年10月25日 11:05:30   作者:nbplus_007  
ZAP是由Uber開源的高性能Go語言日志庫,支持多種日志級別及基本信息打印,雖然ZAP本身不支持日志分割,但可以結(jié)合lumberjack進行日志切割,實現(xiàn)日志按文件大小、時間或間隔切割等功能,ZAP提供Logger和SugaredLogger兩種日志記錄器

golang 日志庫ZAP[uber-go zap] 

1. 簡要說明

zap 是 uber 開源的 Go 高性能日志庫,支持不同的日志級別, 能夠打印基本信息等,但不支持日志的分割,這里我們可以使用 lumberjack 也是 zap 官方推薦用于日志分割,結(jié)合這兩個庫我們就可以實現(xiàn)以下功能的日志機制:

能夠?qū)⑹录涗浀轿募?,而不是?yīng)用程序控制臺;日志切割能夠根據(jù)文件大小、時間或間隔等來切割日志文件;支持不同的日志級別,例如 DEBUG , INFO , WARN , ERROR 等;能夠打印基本信息,如調(diào)用文件、函數(shù)名和行號,日志時間等;官網(wǎng)地址:https://github.com/uber-go/zap

2. 下載安裝

// 初始化go mod 通過mod管理擴展包
go mod init zaplog
//使用下面命令安裝
go get -u go.uber.org/zap
//如果下載失敗,則使用以下命令重新下載安裝
go get github.com/uber-go/zap
//下載安裝成功后還有如下提示:
package github.com/uber-go/zap: code in directory 
src/github.com/uber-go/zap expects import "go.uber.org/zap"

3. 配置 zap Logger

zap 提供了兩種類型的日志記錄器—和 Logger 和 Sugared Logger 。兩者之間的區(qū)別是:

  • 在每一微秒和每一次內(nèi)存分配都很重要的上下文中,使用Logger。它甚至比SugaredLogger更快,內(nèi)存分配次數(shù)也更少,但它只支持強類型的結(jié)構(gòu)化日志記錄。
  • 在性能很好但不是很關(guān)鍵的上下文中,使用SugaredLogger。它比其他結(jié)構(gòu)化日志記錄包快 4-10 倍,并且支持結(jié)構(gòu)化和 printf 風格的日志記錄。
  • 所以一般場景下我們使用 Sugared Logger 就足夠了。

3.1 Logger

  • 通過調(diào)用zap.NewProduction()/zap.NewDevelopment()或者zap.NewExample()創(chuàng)建一個 Logger 。
  • 上面的每一個函數(shù)都將創(chuàng)建一個 logger 。唯一的區(qū)別在于它將記錄的信息不同。例如 production logger 默認記錄調(diào)用函數(shù)信息、日期和時間等。
  • 通過 Logger 調(diào)用 INFO 、 ERROR 等。
  • 默認情況下日志都會打印到應(yīng)用程序的 console 界面。

3.1.1 NewExample

//代碼示例:
package main
import (
	"go.uber.org/zap"
)
func main() {
	log := zap.NewExample()
	log.Debug("this is debug message")
	log.Info("this is info message")
	log.Info("this is info message with fileds",
		zap.Int("age", 24), zap.String("agender", "man"))
	log.Warn("this is warn message")
	log.Error("this is error message")
	log.Panic("this is panic message")
}
//輸出結(jié)果:
{"level":"debug","msg":"this is debug message"}
{"level":"info","msg":"this is info message"}
{"level":"info","msg":"this is info message with fileds","age":24,"agender":"man"}
{"level":"warn","msg":"this is warn message"}
{"level":"error","msg":"this is error message"}
{"level":"panic","msg":"this is panic message"}
panic: this is panic message

3.1.2 NewDevelopment

//代碼示例:
func main() {
	log, _ := zap.NewDevelopment()
	log.Debug("this is debug message")
	log.Info("this is info message")
	log.Info("this is info message with fileds",
		zap.Int("age", 24), zap.String("agender", "man"))
	log.Warn("this is warn message")
	log.Error("this is error message") 
	// log.DPanic("This is a DPANIC message")	
	// log.Panic("this is panic message")
	// log.Fatal("This is a FATAL message")
}
//輸出結(jié)果:
2020-06-12T18:51:11.457+0800	DEBUG	task/main.go:9	this is debug message
2020-06-12T18:51:11.457+0800	INFO	task/main.go:10	this is info message
2020-06-12T18:51:11.457+0800	INFO	task/main.go:11	this is info message with fileds	{"age": 24, "agender": "man"}
2020-06-12T18:51:11.457+0800	WARN	task/main.go:13	this is warn message
main.main
	/home/wohu/GoCode/src/task/main.go:13
runtime.main
	/usr/local/go/src/runtime/proc.go:200
2020-06-12T18:51:11.457+0800	ERROR	task/main.go:14	this is error message
main.main
	/home/wohu/GoCode/src/task/main.go:14
runtime.main
	/usr/local/go/src/runtime/proc.go:200

3.1.3 NewProduction

代碼示例:
func main() {
	log, _ := zap.NewProduction()
	log.Debug("this is debug message")
	log.Info("this is info message")
	log.Info("this is info message with fileds",
		zap.Int("age", 24), zap.String("agender", "man"))
	log.Warn("this is warn message")
	log.Error("this is error message") 
	// log.DPanic("This is a DPANIC message")	
	// log.Panic("this is panic message")
	// log.Fatal("This is a FATAL message")
}
輸出結(jié)果:
{"level":"info","ts":1591959367.316352,"caller":"task/main.go:10","msg":"this is info message"}
{"level":"info","ts":1591959367.3163702,"caller":"task/main.go:11","msg":"this is info message with fileds","age":24,"agender":"man"}
{"level":"warn","ts":1591959367.3163917,"caller":"task/main.go:13","msg":"this is warn message"}
{"level":"error","ts":1591959367.3163974,"caller":"task/main.go:14","msg":"this is error message","stacktrace":"main.main\n\t/home/wohu/GoCode/src/task/main.go:14\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:200"}

3.1.4 對比總結(jié)

Example和Production使用的是 json 格式輸出,Development 使用行的形式輸出

  • Development
    • 從警告級別向上打印到堆棧中來跟蹤
    • 始終打印包/文件/行(方法)
    • 在行尾添加任何額外字段作為 json 字符串
    • 以大寫形式打印級別名稱
    • 以毫秒為單位打印 ISO8601 格式的時間戳
  • Production
    • 調(diào)試級別消息不記錄
    • Error , Dpanic 級別的記錄,會在堆棧中跟蹤文件, Warn 不會
    • 始終將調(diào)用者添加到文件中
    • 以時間戳格式打印日期
    • 以小寫形式打印級別名稱
    • 在上面的代碼中,我們首先創(chuàng)建了一個 Logger ,然后使用 Info / Error 等 Logger 方法記錄消息。

日志記錄器方法的語法是這樣的:

func (log *Logger) MethodXXX(msg string, fields ...Field)

其中 MethodXXX 是一個可變參數(shù)函數(shù),可以是 Info / Error / Debug / Panic 等。每個方法都接受一個消息字符串和任意數(shù)量的 zapcore.Field 長參數(shù)。

每個 zapcore.Field 其實就是一組鍵值對參數(shù)。

3.2 Sugared Logger

默認的 zap 記錄器需要結(jié)構(gòu)化標簽,即對每個標簽,需要使用特定值類型的函數(shù)。

log.Info("this is info message with fileds",zap.Int("age", 24), zap.String("agender", "man"))

雖然會顯的很長,但是對性能要求較高的話,這是最快的選擇。也可以使用suger logger, 它基于 printf 分割的反射類型檢測,提供更簡單的語法來添加混合類型的標簽。

我們使用 Sugared Logger 來實現(xiàn)相同的功能。

  • 大部分的實現(xiàn)基本都相同;
  • 惟一的區(qū)別是,我們通過調(diào)用主 logger 的.Sugar()方法來獲取一個SugaredLogger;
  • 然后使用SugaredLogger以printf格式記錄語句;
func main() {
	logger, _ := zap.NewDevelopment()
	slogger := logger.Sugar()
	slogger.Debugf("debug message age is %d, agender is %s", 19, "man")
	slogger.Info("Info() uses sprint")
	slogger.Infof("Infof() uses %s", "sprintf")
	slogger.Infow("Infow() allows tags", "name", "Legolas", "type", 1)
}
//輸出結(jié)果:
2020-06-12T19:23:54.184+0800	DEBUG	task/main.go:11	debug message age is 19, agender is man
2020-06-12T19:23:54.185+0800	INFO	task/main.go:12	Info() uses sprint
2020-06-12T19:23:54.185+0800	INFO	task/main.go:13	Infof() uses sprintf
2020-06-12T19:23:54.185+0800	INFO	task/main.go:14	Infow() allows tags	{"name": "Legolas", "type": 1}

如果需要,可以隨時使用記錄器上的 .Desugar() 方法從 sugar logger 切換到標準記錄器。

log := slogger.Desugar()
log.Info("After Desugar; INFO message")
log.Warn("After Desugar; WARN message")
log.Error("After Desugar; ERROR message")

4. 將日志寫入文件

我們將使用zap.New(…)方法來手動傳遞所有配置,而不是使用像zap.NewProduction()這樣的預(yù)置方法來創(chuàng)建 logger 。

func New(core zapcore.Core, options ...Option) *Logger

zapcore.Core需要三個配置——Encoder,WriteSyncer,LogLevel。

Encoder :編碼器(如何寫入日志)。我們將使用開箱即用的 NewConsoleEncoder() ,并使用預(yù)先設(shè)置的 ProductionEncoderConfig() 。

zapcore.NewConsoleEncoder(zap.NewProductionEncoderConfig())

WriterSyncer :指定日志將寫到哪里去。我們使用 zapcore.AddSync() 函數(shù)并且將打開的文件句柄傳進去。

file, _ := os.Create("./test.log") 
writeSyncer := zapcore.AddSync(file)

Log Level :哪種級別的日志將被寫入。

// 代碼示例:
package main
import (
	"os"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)
var sugarLogger *zap.SugaredLogger
func InitLogger() {
	encoder := getEncoder()
	writeSyncer := getLogWriter()
	core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
	// zap.AddCaller()  添加將調(diào)用函數(shù)信息記錄到日志中的功能。
	logger := zap.New(core, zap.AddCaller())
	sugarLogger = logger.Sugar()
}
func getEncoder() zapcore.Encoder {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder // 修改時間編碼器
	// 在日志文件中使用大寫字母記錄日志級別
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	// NewConsoleEncoder 打印更符合人們觀察的方式
	return zapcore.NewConsoleEncoder(encoderConfig)
}
func getLogWriter() zapcore.WriteSyncer {
	file, _ := os.Create("./test.log")
	return zapcore.AddSync(file)
}
func main() {
	InitLogger()
	sugarLogger.Info("this is info message")
	sugarLogger.Infof("this is %s, %d", "aaa", 1234)
	sugarLogger.Error("this is error message")
	sugarLogger.Info("this is info message")
}
// 輸出日志文件:
2020-06-16T09:01:06.192+0800	INFO	task/main.go:40	this is info message
2020-06-16T09:01:06.192+0800	INFO	task/main.go:41	this is aaa, 1234
2020-06-16T09:01:06.192+0800	ERROR	task/main.go:42	this is error message
2020-06-16T09:01:06.192+0800	INFO	task/main.go:43	this is info message

到此這篇關(guān)于golang 日志庫ZAP[uber-go zap]詳解的文章就介紹到這了,更多相關(guān)golang 日志庫ZAP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang 類型轉(zhuǎn)換的實現(xiàn)(斷言、強制、顯式類型)

    Golang 類型轉(zhuǎn)換的實現(xiàn)(斷言、強制、顯式類型)

    將一個值從一種類型轉(zhuǎn)換到另一種類型,便發(fā)生了類型轉(zhuǎn)換,在go可以分為斷言、強制、顯式類型轉(zhuǎn)換,本文就詳細的介紹一下這就幾種轉(zhuǎn)換方式,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • Go 類型轉(zhuǎn)換工具包strconv包的用法

    Go 類型轉(zhuǎn)換工具包strconv包的用法

    Go 語言的?strconv?包提供了用于基本數(shù)據(jù)類型之間轉(zhuǎn)換的函數(shù),本文主要介紹了Go 類型轉(zhuǎn)換工具包strconv包的用法,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • go語言通過結(jié)構(gòu)體生成json示例解析

    go語言通過結(jié)構(gòu)體生成json示例解析

    這篇文章主要為大家介紹了go語言通過結(jié)構(gòu)體生成json示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • Golang常用環(huán)境變量說明與設(shè)置詳解

    Golang常用環(huán)境變量說明與設(shè)置詳解

    這篇文章主要介紹了Golang常用環(huán)境變量說明與設(shè)置,需要的朋友可以參考下
    2020-02-02
  • 深入理解Golang的反射reflect示例

    深入理解Golang的反射reflect示例

    本文主要介紹了Golang的反射reflect示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Golang中slice刪除元素的性能對比

    Golang中slice刪除元素的性能對比

    go沒有對刪除切片元素提供專用的語法或者接口,需要使用切片本身的特性來刪除元素,下面這篇文章主要給大家介紹了關(guān)于Golang中slice刪除元素的性能對比,需要的朋友可以參考下
    2022-06-06
  • Golang中反射的常見用法分享

    Golang中反射的常見用法分享

    本篇文章主要為大家詳細介紹一些Go語言中常見的反射用法,涵蓋了常見的數(shù)據(jù)類型的反射操作。文中的示例代碼講解詳細,感興趣的可以了解一下
    2023-01-01
  • 詳解go語言中sort如何排序

    詳解go語言中sort如何排序

    我們的代碼業(yè)務(wù)中很多地方需要我們自己進行排序操作,本文主要介紹了詳解go語言中sort如何排序,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 淺談go語言閉包的立即執(zhí)行和不立即執(zhí)行

    淺談go語言閉包的立即執(zhí)行和不立即執(zhí)行

    Go語言中的閉包是一種可以訪問其定義時所在作用域變量的特殊函數(shù),閉包可以分為立即執(zhí)行和不立即執(zhí)行兩種,本文就來介紹一下go語言閉包的立即執(zhí)行和不立即執(zhí)行,感興趣的可以了解一下
    2025-03-03
  • Qt6.5 grpc組件使用 + golang grpc server示例詳解

    Qt6.5 grpc組件使用 + golang grpc server

    這篇文章主要介紹了Qt6.5 grpc組件使用+golang grpc server示例,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05

最新評論