Patryk
Patryk

Reputation: 24130

How to add custom (non const) string information to log format?

I have started working with logging in Go and I have encountered this article about logging in Go https://www.goinggo.net/2013/11/using-log-package-in-go.html

with the following source code (slightly changed):

var (
  Trace   *log.Logger
  Info    *log.Logger
  Warning *log.Logger
  Error   *log.Logger
)

func Init(
    traceHandle io.Writer,
    infoHandle io.Writer,
    warningHandle io.Writer,
    errorHandle io.Writer) {

    Trace = log.New(traceHandle,
        “TRACE: “,
        log.Ldate|log.Ltime|log.Lshortfile)

    Info = log.New(infoHandle,
        “INFO: “,
        log.Ldate|log.Ltime|log.Lshortfile)

    Warning = log.New(warningHandle,
        “WARNING: “,
        log.Ldate|log.Ltime|log.Lshortfile)

    Error = log.New(errorHandle,
        “ERROR: “,
        log.Ldate|log.Ltime|log.Lshortfile)
}

func main() {
  Init(ioutil.Discard, os.Stdout, os.Stdout, os.Stderr)
}

now I would like to add some custom information to log entries produced by this logger but which are not const string literals (like added there INFO: or WARNING:)

For example I would like to add a name of the function in which the log has been triggered. Let's say I have the following function which I would like to use for this: (from here)

func _enter() {
  // Skip this function, and fetch the PC and file for its parent
  pc, _, _, _ := runtime.Caller(1)
  // Retrieve a Function object this functions parent
  functionObject := runtime.FuncForPC(pc)
  // Regex to extract just the function name (and not the module path)
  extractFnName := regexp.MustCompile(`^.*\.(.*)$`)
  fnName := extractFnName.ReplaceAllString(functionObject.Name(), "$1")
  fmt.Printf("Entering %s\n", fnName)
}

How can I add this to the logger?

Upvotes: 0

Views: 93

Answers (1)

matt.s
matt.s

Reputation: 1746

  • The simplest answer of course is to just type it in when you write the line of logging. Lots of libraries actually use a convention like

    logger.Logf("myfilename.go:123" + "other logging info")

    where 123 is the line number. This is pretty scriptable by an ide or editor as well.

  • If you change _enter() to return the name of the function, that would make the rest of this much simpler. You can call logger.SetPrefix() inside each function, which might look like the following based on your example code.

    Info.SetPrefix("INFO: " + _enter() + ":")

    You could wrap the logger in a struct that would help do the above automatically, but you should be aware of the overhead of making the call to _enter() every time.

  • Though at this point, you might want to look into using a logging library with more features. I have had good experiences with logrus which can be a drop in replacement for the standard lib's log package.

Upvotes: 1

Related Questions