Uber Zap logger function name in logs

5k Views Asked by At

How to get function name printed in logs from Uber Zap logging ? This is the PR request with which they seemed to have added the functionality to output function names in log.

I am using golang version 1.15 and go.uber.org/zap v1.16.0

This is my code:

package main

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

var logger *zap.Logger

func main() {
    logger := NewLogger()
    logger.Info("Test msg Main")
    TestFunc(logger)
}

func TestFunc(logger *zap.Logger)  {
    logger.Info("Test msg TestFunc")
}

func NewLogger() *zap.Logger {
    config := zap.NewDevelopmentConfig()
    opts := []zap.Option{
        zap.AddCallerSkip(1), // traverse call depth for more useful log lines
        zap.AddCaller(),
    }

    logger, _ = config.Build(opts...)
    return logger
}

This is the output I get with/without the addition of AddCaller() option

2021-03-01T15:00:02.927-0800    INFO    runtime/proc.go:204     Test msg Main
2021-03-01T15:00:02.927-0800    INFO    cmd/main.go:12  Test msg TestFunc

I am expecting something like

   2021-03-01T15:00:02.927-0800    INFO    runtime/proc.go:204   main  Test msg Main
   2021-03-01T15:00:02.927-0800    INFO    cmd/main.go:12  TestFunc Test msg TestFunc
1

There are 1 best solutions below

0
On BEST ANSWER

By default, the provided encoder presets (NewDevelopmentEncoderConfig used by NewDevelopmentConfig and NewProductionEncoderConfig used by NewProductionConfig) do not enable function name logging.

To enable function name, you need to enable caller (true by default) and set a non-empty value for config.EncoderConfig.FunctionKey.

Source: EncoderConfig

type EncoderConfig struct {
    // Set the keys used for each log entry. If any key is empty, that portion
    // of the entry is omitted.
    ...
    CallerKey     string `json:"callerKey" yaml:"callerKey"`
    FunctionKey   string `json:"functionKey" yaml:"functionKey"` // this needs to be set
    StacktraceKey string `json:"stacktraceKey" yaml:"stacktraceKey"`
    ...
}

Example Console Logger:

func main() {
    config := zap.NewDevelopmentConfig()
    // if you're using console encoding, the FunctionKey value can be any
    // non-empty string because console encoding does not print the key.
    config.EncoderConfig.FunctionKey = "F"
    logger, _ := config.Build()
    logger.Info("Test Logging")
    // Output: 2021-03-03T11:41:47.728+0800    INFO    example/main.go:11     main.main       Test Logging
}

Example JSON Logger:

func main() {
    config := zap.NewProductionConfig()
    // the FunctionKey value matters because it will become the JSON field
    config.EncoderConfig.FunctionKey = "func"
    logger, _ := config.Build()
    log(logger)
    // Output: {"level":"info","ts":1614743088.538128,"caller":"example/main.go:15","func":"main.log","msg":"Test Logging"}
}

func log(logger *zap.Logger) {
    logger.Info("Test Logging")
}