golang中使用zap日志库

1. 快速使用

package main

import (
	"go.uber.org/zap"
	"time"
)

func main() {
	// 1. sugar日志
	//logger, _ := zap.NewProduction()
	//logger, _ := zap.NewDevelopment()
	//defer logger.Sync()  // 刷新缓冲区,存盘
	//sugar := logger.Sugar()
	//sugar.Infow("first logger",
	// 结构化上下文为松散类型的键值对。
	//	"url", "https://sankuanedu.com",
	//	"name", "三宽教育",
	//)
	//sugar.Errorf("url: %s", "http://www.mayanan.cn")

	// 测试环境
	// 输出:2022-01-17T15:36:40.833+0800	INFO	zapTest/main.go:11	first logger	{"url": "https://sankuanedu.com", "name": "三宽教育"}
	// 输出:2022-01-17T15:51:18.915+0800	ERROR	zapTest/main.go:16	url: http://www.mayanan.cn
	//main.main
	//	C:/Users/mayanan/Desktop/pro_go/zapTest/main.go:16
	//runtime.main
	//	D:/go_1_17_1/src/runtime/proc.go:255

	// 正式环境
	// {"level":"info","ts":1642405507.5565631,"caller":"zapTest/main.go:11","msg":"first logger","url":"https://sankuanedu.com","name":"三宽教育"}
	// {"level":"error","ts":1642405507.5565631,"caller":"zapTest/main.go:16","msg":"url: http://www.mayanan.cn","stacktrace":"main.main\n\tC:/Users/mayanan/Desktop/pro_go/zapTest/main.go:16\nruntime.main\n\tD:/go_1_17_1/src/runtime/proc.go:255"}


	// 2. 高性能日志
	// 当性能和类型安全至关重要时,请使用记录器。它甚至比 SugaredLogger 更快,分配也更少,但它只支持结构化日志记录。
	logger, _ := zap.NewProduction()
	//logger, _ := zap.NewDevelopment()
	defer logger.Sync()  // 刷新缓冲区,存盘
	logger.Debug("faild to fetch url",
		// 作为强类型字段值的结构化上下文.
		zap.String("url", "https://www.mayanan.cn"),
		zap.Int("age", 28),
		zap.Duration("duration", time.Second),
	)
	// 输出结构跟sugar一致

}

由于zap日志zap.NewProduction()和zap.NewDevelopment()默认是将日志输出到控制台,我们生产中需要将日志写入到文件

定义logger,将日志写入文件而不是终端(zap.SugaredLogger)

package main

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

var sugarLogger *zap.SugaredLogger

func main() {
	InitLogger()
	defer sugarLogger.Sync()
	for i := 0; i < 10000; i++ {
		simpleHttpGet("www.sogo.com")
		simpleHttpGet("http://www.sogo.com")
	}
}

func InitLogger() {
	writeSyncer := getLogWriter()
	encoder := getEncoder()
	core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)

	logger := zap.New(core, zap.AddCaller())
	sugarLogger = logger.Sugar()
}

func getEncoder() zapcore.Encoder {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	//return zapcore.NewJSONEncoder(encoderConfig)
	return zapcore.NewConsoleEncoder(encoderConfig)
}

func getLogWriter() zapcore.WriteSyncer {
	lumberJackLogger := &lumberjack.Logger{
		Filename:   "./test.log",
		MaxSize:    1,
		MaxBackups: 5,
		MaxAge:     30,
		Compress:   false,
		LocalTime: true,
	}
	return zapcore.AddSync(lumberJackLogger)
}

func simpleHttpGet(url string) {
	sugarLogger.Debugf("Trying to hit GET request for %s", url)
	//resp, err := http.Get(url)
	//if err != nil {
	//	sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err)
	//} else {
	//	sugarLogger.Infof("Success! statusCode = %s for URL %s", resp.Status, url)
	//	resp.Body.Close()
	//}

	sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, "这是一个错误")
	sugarLogger.Infof("Success! statusCode = %d for URL %s", 200, url)
}

日志输出结果图:

参考文档:zap+Lumberjack 记录日志同时实现日志切割归档

高性能日志输出到(zap.Logger)

点击查看代码
package main

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"time"
)

//var sugarLogger *zap.SugaredLogger
var logger *zap.Logger

func main() {
	InitLogger()
	defer logger.Sync()
	for i := 0; i < 10000; i++ {
		simpleHttpGet("www.sogo.com")
		simpleHttpGet("http://www.sogo.com")
	}
}

func InitLogger() {
	writeSyncer := getLogWriter()
	encoder := getEncoder()
	core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)

	logger = zap.New(core, zap.AddCaller())
}

func getEncoder() zapcore.Encoder {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	return zapcore.NewJSONEncoder(encoderConfig)
	//return zapcore.NewConsoleEncoder(encoderConfig)
}

func getLogWriter() zapcore.WriteSyncer {
	lumberJackLogger := &lumberjack.Logger{
		Filename:   "./test.log",
		MaxSize:    1,
		MaxBackups: 5,
		MaxAge:     30,
		Compress:   false,
		LocalTime: true,
	}
	return zapcore.AddSync(lumberJackLogger)
}

func simpleHttpGet(url string) {
	logger.Debug("这是一条DEBUG的信息:",
		zap.String("name", "sankaun"),
		zap.Int("age", 18),
	)
	//resp, err := http.Get(url)
	//if err != nil {
	//	sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err)
	//} else {
	//	sugarLogger.Infof("Success! statusCode = %s for URL %s", resp.Status, url)
	//	resp.Body.Close()
	//}

	logger.Error("这是一条Error的信息",
		zap.Time("now", time.Now()),
		zap.Bool("bool", false),
	)
	logger.Info("这是一条Info的信息",
		zap.Duration("now", time.Second * 3),
		zap.Bool("bool", true),
	)
}

高性能日志输出到(zap.Logger),不同日志类型存储到不同目录文件

结构图:

点击查看代码
package main

import (
	"github.com/natefinch/lumberjack"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"time"
)

var infoLogger *zap.Logger
var errLogger *zap.Logger
var otherLogger *zap.Logger

func main() {
	InitLogger()
	defer infoLogger.Sync()
	defer errLogger.Sync()
	defer otherLogger.Sync()
	for i := 0; i < 10000; i++ {
		simpleHttpGet("www.sogo.com")
		simpleHttpGet("http://www.sogo.com")
	}
}

func InitLogger() {
	infoWriteSyncer := getLogWriter("info")
	errWriteSyncer := getLogWriter("error")
	otherWriteSyncer := getLogWriter("other")
	encoder := getEncoder()
	infoCore := zapcore.NewCore(encoder, infoWriteSyncer, zapcore.InfoLevel)
	errCore := zapcore.NewCore(encoder, errWriteSyncer, zapcore.ErrorLevel)
	otherCore := zapcore.NewCore(encoder, otherWriteSyncer, zapcore.DebugLevel)

	infoLogger = zap.New(infoCore, zap.AddCaller())
	errLogger = zap.New(errCore, zap.AddCaller())
	otherLogger = zap.New(otherCore, zap.AddCaller())
}

func getEncoder() zapcore.Encoder {
	encoderConfig := zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	return zapcore.NewJSONEncoder(encoderConfig)
	//return zapcore.NewConsoleEncoder(encoderConfig)
}

func getLogWriter(infoOrErr string) zapcore.WriteSyncer {
	var lumberJackLogger *lumberjack.Logger
	if infoOrErr == "info" {
		lumberJackLogger = &lumberjack.Logger{
			Filename:   "./info/info.log",
			MaxSize:    1,
			MaxBackups: 5,
			MaxAge:     30,
			Compress:   false,
			LocalTime: true,
		}
	} else if infoOrErr == "error"{
		lumberJackLogger = &lumberjack.Logger{
			Filename:   "./error/error.log",
			MaxSize:    1,
			MaxBackups: 5,
			MaxAge:     30,
			Compress:   false,
			LocalTime: true,
		}
	} else {
		lumberJackLogger = &lumberjack.Logger{
			Filename:   "./other/other.log",
			MaxSize:    1,
			MaxBackups: 5,
			MaxAge:     30,
			Compress:   false,
			LocalTime: true,
		}
	}
	return zapcore.AddSync(lumberJackLogger)
}

func simpleHttpGet(url string) {
	otherLogger.Debug("这是一条DEBUG的信息:",
		zap.String("name", "sankaun"),
		zap.Int("age", 18),
	)
	//resp, err := http.Get(url)
	//if err != nil {
	//	sugarLogger.Errorf("Error fetching URL %s : Error = %s", url, err)
	//} else {
	//	sugarLogger.Infof("Success! statusCode = %s for URL %s", resp.Status, url)
	//	resp.Body.Close()
	//}

	errLogger.Error("这是一条Error的信息",
		zap.Time("now", time.Now()),
		zap.Bool("bool", false),
	)
	infoLogger.Info("这是一条Info的信息",
		zap.Duration("now", time.Second * 3),
		zap.Bool("bool", true),
	)
}

go.uber.org/zap
zap官方文档

补充-日志输出到文件和stderr-简单方法

func NewLogger() (*zap.Logger, error) {
	// 日志输出到文件配置
	cfg := zap.NewProductionConfig()
	cfg.OutputPaths = []string{
		"stderr",
		"./myproject.log",
	}
	return cfg.Build()
}

func main() {
	//logger, _ := zap.NewProduction()
	logger, err := NewLogger()
	if err != nil {
		// 初始化logger失败
		panic(err)
	}
	sugar := logger.Sugar()
	defer sugar.Sync()  // 刷新缓冲区,存盘
	sugar.Infow("这是第一条日志消息", "name", "三三", "age", 99)
}

zap.S()函数和zap.L()函数

zap.S()函数和zap.L()函数很有用: 提供了一个全局的安全访问logger的途径

func InitLogger() {
	//logger, _ := zap.NewProduction()  // 生产日志
	logger, _ := zap.NewDevelopment()  // 开发日志
	zap.ReplaceGlobals(logger)
	// zap.S()可以获取一个全局的sugar, 可以让我们自己设置一个全局的logger
	// 日志是分级别的:debug info warning error fatal
	// zap.S()函数和zap.L()函数很有用: 提供了一个全局的安全访问logger的途径
}

func main() {
	port := 8021

	// 初始化日志
	initialize.InitLogger()

	// 初始化routers
	router := initialize.Routers()

	zap.S().Debugf("开启服务,端口:%d", port)

	if err := router.Run(fmt.Sprintf(":%d", port)); err != nil {
		zap.S().Panic("服务启动失败", err.Error())
	}

}

posted @ 2022-01-17 17:29  专职  阅读(1346)  评论(0编辑  收藏  举报