(Zap log framework, Go) Initialize log once and reuse from other Go file (Solved)

纵饮孤独 提交于 2021-01-22 03:16:13

问题


I'm trying to migrate my application from the beautiful Logrus (very helpful for debug) and introducing the Uber log framework Zap.

With Logrus, i can initialize the logger only once and reuse it from other Go file, an example:

package main
import(
    // Print filename on log
    filename "github.com/onrik/logrus/filename"
    // Very nice log library
    log "github.com/sirupsen/logrus"
)

func main(){

// ==== SET LOGGING
    Formatter := new(log.TextFormatter)
    Formatter.TimestampFormat = "Jan _2 15:04:05.000000000"
    Formatter.FullTimestamp = true
    Formatter.ForceColors = true
    log.AddHook(filename.NewHook()) // Print filename + line at every log
    log.SetFormatter(Formatter)

}

From other Go file, i'm able to reuse that logger without any other initialization:

// VerifyCommandLineInput is delegated to manage the inputer parameter provide with the input flag from command line
func VerifyCommandLineInput() datastructures.Configuration {
    log.Debug("VerifyCommandLineInput | Init a new configuration from the conf file")
    c := flag.String("config", "./conf/test.json", "Specify the configuration file.")
    flag.Parse()
    if strings.Compare(*c, "") == 0 {
        log.Fatal("VerifyCommandLineInput | Call the tool using --config conf/config.json")
    }
    file, err := os.Open(*c)
    if err != nil {
        log.Fatal("VerifyCommandLineInput | can't open config file: ", err)
    }
    defer file.Close()
    decoder := json.NewDecoder(file)
    cfg := datastructures.Configuration{}
    err = decoder.Decode(&cfg)
    if err != nil {
        log.Fatal("VerifyCommandLineInput | can't decode config JSON: ", err)
    }
    log.Debug("VerifyCommandLineInput | Conf loaded -> ", cfg)

    return cfg
}

My question is:
Using the Zap log framework, how can i initialize the log in the main function and use that logger from the other Go file?


Solution:

Initialize a new log and set as global as pointed by @Mikhail.

package main

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

func initZapLog() *zap.Logger {
    config := zap.NewDevelopmentConfig()
    config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder
    config.EncoderConfig.TimeKey = "timestamp"
    config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
    logger, _ := config.Build()
    return logger
}

func main() {

    loggerMgr := initZapLog()
    zap.ReplaceGlobals(loggerMgr)
    defer loggerMgr.Sync() // flushes buffer, if any
    logger := loggerMgr.Sugar()
    logger.Debug("START!")
    db2.GetToken(`alessio`, `savi`, `pass`)
    datastructure.LoadConfiguration()
}

Than you can use the logger in the other Go file:

func GetToken(url, user, pass string) string {
    var User datastructure.User
    var data string
    var jsonData []byte

    User.User = user
    User.Pass = pass
    jsonData, err := json.Marshal(User)
    if err != nil {
        zap.S().Errorw("Error during marshalling...", err)
        return ""
    }
    data = string(jsonData)
    zap.S().Info("Data encoded => ", data)
    return ""
}

回答1:


You can set up your logger in the main function and call https://godoc.org/go.uber.org/zap#ReplaceGlobals to use it as a default global logger.




回答2:


Replacing the default go Global logger with zaps' implementation is possible, but discouraged.

Per their FAQ

Why include package-global loggers? Since so many other logging packages include a global logger, many applications aren't designed to accept loggers as explicit parameters. Changing function signatures is often a breaking change, so zap includes global loggers to simplify migration.

Avoid them where possible.

Depending on your needs, you can create a logger in main and pass it around or create a new logger in each package. I elected to create one in main and pass it around since I'm using an Atomic logger, which allows me to change log levels while my app is running via an API call. With a long history of using DI and consolidating code in general it does feel like code smell, but apparently it's significantly more performant for how zap works to pass it around over a singleton or global.



来源:https://stackoverflow.com/questions/57745017/zap-log-framework-go-initialize-log-once-and-reuse-from-other-go-file-solved

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!