• 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人 ... 如发现博客错误,可直接留言指正,感谢。
  • 相关阅读:
    The last access date is not changed even after reading the file on Windows 7
    渗透基础——获得当前系统已安装的程序列表
    Top 10 Best Free Netflow Analyzers and Collectors for Windows
    平安科技移动开发二队技术周报(第十五期)
    Intent传递对象的几种方式
    SQLite基础学习
    2 Java基础语法(keyword,标识符,凝视,常量,进制转换,变量,数据类型,数据类型转换)
    iOS 之应用性能调优的25个建议和技巧
    Fragment事务管理源代码分析
    CMake
  • 原文地址:https://www.cnblogs.com/leohahah/p/14566463.html
Copyright © 2020-2023  润新知