Go日志模块: log简介

参考链接:

本文不对各个模块做详细的讲解,可参考上述链接查看各个模块的docs,本文目的为:提供一个生产可用的logging代码示例。
一个简单Demo:
import (
    "log"
)

func main() {
    log.Print("Logging in Go!")
}

log模块的Fatal与Panic开头的function都会直接终止程序运行,这点需要注意。

log模块只有Print与Fatal、Panic三个level对应的函数,可以通过SetOutput函数定义输出目的地,如下为输出至文件的示例。

package main

import (
    "log"
    "os"
)

func main() {
    file, err := os.OpenFile("info.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
    if err != nil {
        log.Fatal(err)
    }

    defer file.Close()

    log.SetOutput(file)
    log.Print("Logging to a file in Go!")
}

go源生log包虽然可以用,但相比其他语言的源生log模块和各种定制框架还是弱了很多,uber家的zap是一款比较好的log框架,示例:

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", url,
  "attempt", 3,
  "backoff", time.Second,
)
sugar.Infof("Failed to fetch URL: %s", url)

When performance and type safety are critical, use the Logger. It's even faster than the SugaredLogger and allocates far less, but it only supports structured logging.

推荐下述直接使用logger方法的写法,接收zapcore.Field类型输入,可以有0个或多个输入参数:

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

Output:

{"level":"warn","ts":1616394834.0561035,"caller":"logtest/main.go:12","msg":"failed to fetch URL","url":"www.baidu.com","attempt":3,"backoff":1}

可以看出优点是可以打印出logger发生的代码行数,并且输出了结构化的日志。

我们可以通过封装zap来实现自己的log模块,但没必要因为看到一个比较好用的,就是pingcap家的log模块,用起来比较不错,Demo示例如下:

package main

import (
	"fmt"
	"github.com/pingcap/log"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func main(){
	fmt.Printf("%v
",log.GetLevel())
	log.Debug(`This is a debug message.`, zap.String("lv", "debug"), zap.Int("no", 1))
	log.Info(`This is a info message.`, zap.String("lv", "info"), zap.String("extra", "some extra msg"))
	log.Warn(`This is a warning message.`, zap.String("lv", "warning"), zap.String("extra", "some extra msg"))
	log.SetLevel(zapcore.DebugLevel)
	fmt.Printf("%v
",log.GetLevel())
	log.Debug(`This is a debug message.`, zap.String("lv", "debug"), zap.Int("no", 1))
}

output如下:

可以看到上述非常简洁,但功能强大,各个level的方法可接受多个zap类型的参数,最终打印出来的日志如上,每条日志都标识了发生的代码行数,每条日志的各个部分使用[]进行分隔。

想建一个数据库技术和编程技术的交流群,用于磨炼提升技术能力,目前主要专注于Golang和Python以及TiDB,MySQL数据库,群号:231338927,建群日期:2019.04.26,截止2021.02.01人数:300人 ... 如发现博客错误,可直接留言指正,感谢。
原文地址:https://www.cnblogs.com/leohahah/p/14566463.html