@veryoriginalnickname
Есть логгер zerolog, инициализирую его в переменную Logger, чтоб потом использовать по всему приложению. Хотелось бы добавить в логгер такую штуку, чтоб он выводил еще и место, откуда вызвана функция, типа «main.go:23». Я находил несколько функций, которые позволяют это сделать, имена функций и строка действительно выводились. Но только они все время были в одном месте, независимо от того откуда была вызвана функция, все время было условное «main.go:23».
Если кратко, то: как сделать так, чтоб при каждом вызове Logger, в лог добавлялась функция и строка, откуда он был вызван?
Пока что я остановился на таком неработающем коде:
Если кратко, то: как сделать так, чтоб при каждом вызове Logger, в лог добавлялась функция и строка, откуда он был вызван?
Пока что я остановился на таком неработающем коде:
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, "https://qna.habr.com/")+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()
}
Решения вопроса 1
@veryoriginalnickname
Кажется, теперь работает. Взял кусок кода отсюда и отсюда.
Как я понял: инициализируется Logger, и устанавливается на него хук, в хуке можно получить место, откуда вызвана функция, получаем, и подмешиваем в Logger.
Код получается такой (пишет лог в консоль и в .txt, но тут еще доделать надо чтоб переключался режим дебага на прод и так далее):
Как я понял: инициализируется Logger, и устанавливается на него хук, в хуке можно получить место, откуда вызвана функция, получаем, и подмешиваем в Logger.
Код получается такой (пишет лог в консоль и в .txt, но тут еще доделать надо чтоб переключался режим дебага на прод и так далее):
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, "https://qna.habr.com/")+1:] + ":" + strconv.Itoa(line)
event.Str("caller", filename)
}
}
Пример использования (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.")
}
Вывод (консоль):
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.
Вывод (.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."}
Комментировать
Ответы на вопрос 1
@dimuska139
Вот такой способ вы рассматривали? Тогда в самом верху будет стек вызовов сформирован