Golang一日一库之 日志库 zap

这篇具有很好参考价值的文章主要介绍了Golang一日一库之 日志库 zap。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

在开发过程中 会使用到日志库去记录错误的日志,尤其是golang中 有无穷无尽的error 如果不记录,当你的代码出错,就无从排错了。
zap 是开源的 Go 高性能日志库 主要有以下特点:

  1. 支持不同的日志级别
  2. 能够打印基本信息等但不支持日志的分割 但是可以使用 lumberjack 也是 zap 官方推荐用于日志分割

官网:https://github.com/uber-go/zap
https://pkg.go.dev/go.uber.org/zap#section-readme

安装

go get -u go.uber.org/zap

zap只支持Go的两个最新小版本。

日志记录器 logger和 sugared logger

zap库的使用与其他的日志库非常相似。先创建一个logger,然后调用各个级别的方法记录日志
而 zap库给我们提供两种模式的日志记录

  1. Logger
  2. Sugared Logger
    至于你想问他们之间有什么区别,很简单,我们先来看代码
    这里我就直接用官网的例用代码了

Logger

logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("failed to fetch URL",
	// Structured context as strongly typed Field values.
	zap.String("url", "https://www.baidu.com"),
	zap.Int("attempt", 3),
	zap.Duration("backoff", time.Second),
)

Golang一日一库之 日志库 zap
说实话我是很不喜欢logger模式的日志的
调用起来是真的麻烦 还要指定 int类型 string类型 这个类型那个类型
但优点也很明显那就是 而且内存分配少性能至上

Sugared Logger

logger, _ := zap.NewProduction()
defer logger.Sync() // flushes buffer, if any
sugar := logger.Sugar()
sugar.Infow("failed to fetch URL",
	// Structured context as loosely typed key-value pairs.
	"url", "https://www.baidu.com",
	"attempt", 3,
	"backoff", time.Second,
)
sugar.Infof("Failed to fetch URL: %s", "https://www.baidu.com")

这种就是printf风格的调用起来方便即开即用

Example 和 Production 以及development

Example

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")

结果
Golang一日一库之 日志库 zap

Production

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.Panic("this is panic message")

结果
Golang一日一库之 日志库 zap

NewDevelopment

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.Panic("this is panic message")

结果
Golang一日一库之 日志库 zap

三者对比

由上文可见
Example和Production使用的是json格式
而development使用行的形式
除此之外
Example和Production 所输出的多少也不一样。

具体如下:

Development

  • 从警告级别向上打印到堆栈中来跟踪
  • 始终打印包/文件/行(方法)
  • 在行尾添加任何额外字段作为json字符串
  • 以大写形式打印级别名称
  • 以毫秒为单位打印ISO8601格式的时间戳

Production

  • 调试级别消息不记录
  • Error,Dpanic级别的记录,会在堆栈中跟踪文件,warn不会
  • 始终将调用者添加到文件中
  • 以时间戳格式打印日期
  • 以小写形式打印级别名称

调整日志输出的 格式

如下文代码所示

func getEncoder() zapcore.Encoder {
    encoderConfig := zap.NewDevelopmentEncoderConfig()
    {
        // LevelKey值变为 level
        encoderConfig.LevelKey = "level"
        // MessageKey值变为 msg
        encoderConfig.MessageKey = "msg"
        // TimeKey值 变成time
        encoderConfig.TimeKey = "time"
        // 把输出的info 变成INFO 只需要丢对象 不许执行
        encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
        // 对时间进行格式化处理
        encoderConfig.EncodeTime = func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
            encoder.AppendString(t.Local().Format("2006-01-02 15:04:05"))
        }
    }

    return zapcore.NewJSONEncoder(encoderConfig)
}

如上代码所示,可以调节任意位置,我注释也标的很清楚

使用lumberjack进行配合

官网: https://pkg.go.dev/gopkg.in/natefinch/lumberjack.v2
zap没有切割日志的功能,所以我们必须借助第三方库来实现

使用

要将 lumberjack 与标准库的日志包一起使用,只需在应用程序启动时将其传递到 SetOutput 函数中即可。

log.SetOutput(&lumberjack.Logger{
    Filename:   "/var/log/myapp/foo.log",
    MaxSize:    500, // megabytes
    MaxBackups: 3,
    MaxAge:     28, //days
    Compress:   true, // disabled by default
})

如果要和Zap所结合的话 需要放入到zapcore.AddSync中

zapcore.AddSync(&lumberjack.Logger{
    Filename:   "/var/log/myapp/foo.log",
    MaxSize:    500, // megabytes
    MaxBackups: 3,
    MaxAge:     28, //days
    Compress:   true, // disabled by default
}) 

声明日志并且初始化使用

我们上文以及配置好了日志的格式以及规定了日志输出的位置 也做好了 lumberjack日志的切割
那我们该如何初始化呢
只需要声明core 然后把这三个丢进去即可
如下代码所示

core := zapcore.NewCore(getEncoder(), zapcore.NewMultiWriteSyncer(zapcore.AddSync(&lumberjack.Logger{
    Filename:   "/var/log/myapp/foo.log",
    MaxSize:    500, // megabytes
    MaxBackups: 3,
    MaxAge:     28, //days
    Compress:   true, // disabled by default
}) , zapcore.AddSync(os.Stdout)), zapcore.DebugLevel)
zap.New(core).Sugar()

当然 会发现 我还加了一个值 zapcore.AddSync(os.Stdout))
这句代码是代表除了输出到文件中还会输出到终端中,完成多个终端的输出文章来源地址https://www.toymoban.com/news/detail-411751.html

完整代码 日志库初始化组件

package conf

import (
    "fmt"
    "github.com/natefinch/lumberjack"
    "github.com/spf13/viper"
    "go.uber.org/zap"
    "go.uber.org/zap/zapcore"
    "os"
    "path/filepath"
    "time"
)

func InitLogger() *zap.SugaredLogger {
    logMode := zapcore.InfoLevel

    if viper.GetBool("model.development") {
        logMode = zapcore.DebugLevel
    }
    // 第一个参数是输出的格式 第二个参数 输出的位置

    //zapcore.NewMultiWriteSyncer 输出到多个终端 比如 文件 console中
    core := zapcore.NewCore(getEncoder(), zapcore.NewMultiWriteSyncer(getWriterSyncer(), zapcore.AddSync(os.Stdout)), logMode)
    return zap.New(core).Sugar()
}

// def 输出日志的格式
func getEncoder() zapcore.Encoder {
    encoderConfig := zap.NewDevelopmentEncoderConfig()
    {
        // LevelKey值变为 level
        encoderConfig.LevelKey = "level"
        // MessageKey值变为 msg
        encoderConfig.MessageKey = "msg"
        // TimeKey值 变成time
        encoderConfig.TimeKey = "time"
        // 把输出的info 变成INFO 只需要丢对象 不许执行
        encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
        // 对时间进行格式化处理
        encoderConfig.EncodeTime = func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {
            encoder.AppendString(t.Local().Format("2006-01-02 15:04:05"))
        }
    }

    return zapcore.NewJSONEncoder(encoderConfig)
}

// def 日志要输出到什么地方
func getWriterSyncer() zapcore.WriteSyncer {
    stSeparator := string(filepath.Separator)
    stRootDir, _ := os.Getwd()
    stLogFilePath := stRootDir + stSeparator + "log" + stSeparator + time.Now().Format("2006-01-02") + ".log"
    fmt.Println(stLogFilePath)

    // 日志分割
    hook := lumberjack.Logger{
        Filename:   stLogFilePath,                  // 日志文件路径,默认 os.TempDir()
        MaxSize:    viper.GetInt("log.MaxSize"),    // 每个日志文件保存500M,默认 100M
        MaxBackups: viper.GetInt("log.MaxBackups"), // 保留3个备份,默认不限
        MaxAge:     viper.GetInt("log.MaxAge"),     // 保留28天,默认不限
        Compress:   viper.GetBool("log.Compress"),  // 是否压缩,默认不压缩
    }

    return zapcore.AddSync(&hook)
}

到了这里,关于Golang一日一库之 日志库 zap的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 每日一库:pprof简介

    pprof 是Go语言的一个性能分析库,它可以帮助开发者找出程序中的性能瓶颈。 pprof 提供了CPU分析、内存分析、阻塞分析等多种性能分析功能。 以下是 pprof 的主要特性: CPU分析 : pprof 可以记录程序在CPU上的运行时间,并将这些数据以火焰图的形式展示出来。这可以帮助开发

    2024年02月10日
    浏览(84)
  • 每日一库:fsnotify简介

    fsnotify 是一个用Go编写的文件系统通知库。它提供了一种观察文件系统变化的机制,例如文件的创建、修改、删除、重命名和权限修改。它使用特定平台的事件通知API,例如Linux上的inotify,macOS上的FSEvents,以及Windows上的ReadDirectoryChangesW。 fsnotify 具有以下特点: 跨平台支持

    2024年02月11日
    浏览(41)
  • 每日一库:cobra 简介

    当你需要为你的 Go 项目创建一个强大的命令行工具时,你可能会遇到许多挑战,比如如何定义命令、标志和参数,如何生成详细的帮助文档,如何支持子命令等等。为了解决这些问题, github.com/spf13/cobra 就可以派上用场。 github.com/spf13/cobra 是一个用于构建强大的命令行应用程

    2024年02月08日
    浏览(48)
  • 每日一库:lumberjack -- 日志轮换和管理

    在开发应用程序时,记录日志是一项关键的任务,以便在应用程序运行时追踪问题、监视性能和保留审计记录。Go 语言提供了灵活且强大的日志记录功能,可以通过多种方式配置和使用。其中一个常用的日志记录库是 github.com/natefinch/lumberjack ,它提供了一个方便的方式来处理

    2024年02月08日
    浏览(45)
  • Golang标准库之bytes介绍

    本次主要介绍golang中的标准库 bytes ,基本上参考了 字节 | bytes 、Golang标准库——bytes 文章。 bytes 库主要包含 5 大部分,即: 常量 变量 函数 Buffer Reader 我们依次学习上面的 5 大部分。 bytes.MinRead 是一个常量,表示在使用 ReadFrom 方法从 io.Reader 中读取数据时,每次读取的最小

    2024年02月07日
    浏览(60)
  • golang常用库之-golang-jwt/jwt包

    github: https://github.com/golang-jwt/jwt golang-jwt/jwt 是一个在 Go 语言中使用 JSON Web Tokens(JWT)进行身份验证和授权的库。JWT 是一种用于在跨网络进行安全通信的开放标准(RFC 7519),它使用一个 JSON 对象来表示被声明的安全性信息。 golang-jwt/jwt 包提供了创建、解析和验证 JWT 的功能

    2024年01月23日
    浏览(37)
  • 7天玩转 Golang 标准库之 http/net

    在构建web应用时,我们经常需要处理HTTP请求、做网页抓取或者搭建web服务器等任务,而Go语言在这方面为我们提供了强大的内置工具:net/http标准库,它为我们操作和处理HTTP协议提供了便利。 首先,我们来看看如何使用net/http标准库发送一个HTTP请求。net/http库中的 http.Get 函数

    2024年02月04日
    浏览(50)
  • Ubuntu系统下搭建QtCreator开发环境详细过程(Qt简介;Linux下安装QtCreator)

    关于Qt的相关介绍,可以参考QT从入门到实战x篇,Qt 5.9 C++开发指南,对于重复部分,本栏目不做详细介绍。关于Linux的基础,本人将重新整理一个栏目,就叫 Linux基础 吧,有需要的可以后期关注下。 Qt 是一个跨平台的 C++开发库。主要用来开发图形用户界面 (Graphical User Inter

    2024年02月12日
    浏览(58)
  • Python Web开发库之webargs使用详解

    在现代Web开发中,处理来自客户端的请求参数是一个常见任务。无论是在构建Web API、Web应用程序还是其他Web服务,都需要一种有效的方式来解析、验证和转换这些参数。Python的 Webargs 库是一个功能强大的工具,可以优雅地处理Web请求参数,使开发过程更加简单和可维护。本文

    2024年01月17日
    浏览(39)
  • Golang中记录日志详解

    记录下Golang项目中日志使用,以及结合Gin框架记录请求日志。 rotatelogs \\\"github.com/lestrrat-go/file-rotatelogs github.com/rifflock/lfshook github.com/sirupsen/logrus 这三个包通常被一起使用是为了实现日志文件的轮转(log rotation)功能。解释一下它们的作用: github.com/lestrrat-go/file-rotatelogs : 这是

    2024年01月19日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包