V
V
veryoriginalnickname2021-08-10 17:08:44
go
veryoriginalnickname, 2021-08-10 17:08:44

How to add to the logger the place where the code is called from?

There is a zerolog logger, I initialize it into the Logger variable, so that later I can use it throughout the application. I would like to add such a thing to the logger so that it also displays the place where the function is called from, like "main.go:23". I found several functions that allow you to do this, the names of the functions and the string were actually displayed. But only they were in the same place all the time, regardless of where the function was called from, all the time there was a conditional "main.go:23".
In short, then: how to make it so that with each call to Logger, a function and a line are added to the log, from where it was called?
So far, I've settled on this non-working code:

package _core

import (
  "github.com/rs/zerolog"
  "os"
  "runtime"
  "strconv"
  "strings"
)

var Logger zerolog.Logger

func logger(){
  consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}
  multi := zerolog.MultiLevelWriter(consoleWriter, os.Stdout)
  Logger = zerolog.New(multi).With().Timestamp().Logger()
}


func getFuncName() *zerolog.Logger {
  pc, file, line, ok := runtime.Caller(1)
  if !ok {
    panic("Could not get context info for logger!")
  }
  filename := file[strings.LastIndex(file, "/")+1:] + ":" + strconv.Itoa(line)
  funcname := runtime.FuncForPC(pc).Name()
  fn := funcname[strings.LastIndex(funcname, ".")+1:]
  return Logger.With().Str("file", filename).Str("function", fn).Logger()
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
veryoriginalnickname, 2021-08-10
@veryoriginalnickname

Seems to be working now. I took a piece of code from here and from here .
As I understand it: the Logger is initialized, and a hook is installed on it, in the hook you can get the place where the function is called from, get it, and mix it into the Logger.
The code turns out like this (writes the log to the console and to .txt, but then you still need to finish it so that the debug mode switches to prod, and so on):
logger.go

package _core

import (
  "flag"
  "fmt"
  "github.com/rs/zerolog"
  "log"
  "os"
  "path"
  "runtime"
  "strconv"
  "strings"
)

var Logger zerolog.Logger

func logger(){
  debug := flag.Bool("debug", false, "sets log level to debug")
  flag.Parse()
  zerolog.SetGlobalLevel(zerolog.InfoLevel)
  if *debug {
    zerolog.SetGlobalLevel(zerolog.DebugLevel)
  }
  var logsPath = fmt.Sprintf("%v/_temp/logs/log.txt", GetSrcDir())
  logFile, err := os.Create(logsPath)
  if err != nil {
    log.Fatal(err)
  }
  consoleWriter := zerolog.ConsoleWriter{Out: os.Stdout}
  multi := zerolog.MultiLevelWriter(consoleWriter, logFile)
  Logger = zerolog.New(multi).With().Timestamp().Logger()
  Logger = Logger.Hook(CallerHook{})
}

type CallerHook struct{}
func (h CallerHook) Run(event *zerolog.Event, level zerolog.Level, msg string) {
  if _, file, line, ok := runtime.Caller(3); ok {
    var file = path.Base(file)
    var line = line
    filename := file[strings.LastIndex(file, "/")+1:] + ":" + strconv.Itoa(line)
    event.Str("caller", filename)
  }
}

Usage example (boot.go)
package _core

func Boot()  {
  logger()
  Logger.Info().Msg("boot settings...")
  settings()
  Logger.Info().Msg("boot database...")
  database()
  Logger.Info().Msg("boot routes...")
  routes()
  Logger.Info().Msg("done.")
}

Output (console):
5:59PM INF boot.go:5 > boot settings...
5:59PM INF boot.go:7 > boot database...
5:59PM INF boot.go:9 > boot routes...
5:59PM INF boot.go:11 > done.

Output (.txt):
{"level":"info","time":"2021-08-10T17:59:19+03:00","caller":"boot.go:5","message":"boot settings..."}
{"level":"info","time":"2021-08-10T17:59:19+03:00","caller":"boot.go:7","message":"boot database..."}
{"level":"info","time":"2021-08-10T17:59:20+03:00","caller":"boot.go:9","message":"boot routes..."}
{"level":"info","time":"2021-08-10T17:59:20+03:00","caller":"boot.go:11","message":"done."}

D
Dmitry Sviridov, 2021-08-10
@dimuska139

Is this the way you considered? Then at the very top there will be a call stack formed

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question