自定义模板报 invalid memory address or nil pointer dereference
chanyipiaomiao opened this issue · comments
System (please complete the following information):
- OS: macos
- GO Version: 1.21.5
- Pkg Version: 0.5.5
Describe the bug
自定义模板报空指针 invalid memory address or nil pointer dereference
To Reproduce
func TestLog(t *testing.T) {
myTemplate := "[{{datetime}}] [{{requestid}}] [{{level}}] {{message}}"
textFormatter := &slog.TextFormatter{TimeFormat: "2006-01-02 15:04:05.000"}
textFormatter.SetTemplate(myTemplate)
h1 := handler.NewConsoleHandler(slog.AllLevels)
h1.SetFormatter(textFormatter)
L := slog.New()
L.AddHandlers(h1)
L.WithField("requestid", "11111").Info("testst")
}
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots
Additional context
Add any other context about the problem here.
func TestLog(t *testing.T) {
myTemplate := "[{{datetime}}] [{{requestid}}] [{{level}}] {{message}}"
textFormatter := &slog.TextFormatter{TimeFormat: "2006-01-02 15:04:05.000"}
textFormatter.SetTemplate(myTemplate)
h1 := handler.NewConsoleHandler(slog.AllLevels)
h1.SetFormatter(textFormatter)
ctx := context.WithValue(context.Background(), "requestid", "111111")
L := slog.New()
L.AddHandlers(h1)
L.WithCtx(ctx).Info("test")
}
请问这样使用是否有问题,模板中的requestid没有被替换
改成这样:
myTemplate := "[{{datetime}}] [{{requestid}}] [{{level}}] {{message}}\n"
// textFormatter := &slog.TextFormatter{TimeFormat: "2006-01-02 15:04:05.000"}
// textFormatter.SetTemplate(myTemplate)
// CHANGE 1 ....
textFormatter :=slog.NewTextFormatter(myTemplate).Configure(func(f *slog.TextFormatter) {
f.TimeFormat = "2006-01-02 15:04:05.000"
})
h1 := handler.NewConsoleHandler(slog.AllLevels)
h1.SetFormatter(textFormatter)
ctx := context.WithValue(context.Background(), "requestid", "111111")
L := slog.New()
L.AddHandlers(h1)
// add processor <==== CHANGE 2
L.AddProcessor(slog.ProcessorFunc(func(r *slog.Record) {
r.Fields["requestid"] = r.Ctx.Value("requestid")
}))
L.WithCtx(ctx).Info("test")
- 直接使用
&slog.TextFormatter{}
创建没有初始化字段导致报错。 - 自定义字段需要添加 processor 来设置字段到 record.
请帮忙看看 遇到 panic: assignment to entry in nil map 也不是必现,偶现 具体的错误堆栈信息如下:
panic: assignment to entry in nil map
goroutine 1165 [running]:
devops-alertcenter/internal/pkg/logger.Setup.func2(0xc0003eeb60)
/app/devops_alertcenter/internal/pkg/logger/logger.go:64 +0x65
github.com/gookit/slog.ProcessorFunc.Process(0x9dd6fb?, 0x19b3328?)
/gopath/pkg/mod/github.com/gookit/slog@v0.5.5/processor.go:27 +0x19
github.com/gookit/slog.(*Record).beforeHandle(0xc0003eeb60, 0xc00013e000)
/gopath/pkg/mod/github.com/gookit/slog@v0.5.5/logger_write.go:55 +0x1d5
github.com/gookit/slog.(*Logger).writeRecord(0xc00013e000, 0x258, 0xc0003eeb60)
/gopath/pkg/mod/github.com/gookit/slog@v0.5.5/logger_write.go:71 +0x15a
github.com/gookit/slog.(*Record).logf(0xc0003eeb60, 0x258, {0xc71ea9?, 0x0?}, {0xc000024a80?, 0x2?, 0xc000600400?})
/gopath/pkg/mod/github.com/gookit/slog@v0.5.5/record.go:360 +0xd7
github.com/gookit/slog.(*Record).Infof(...)
/gopath/pkg/mod/github.com/gookit/slog@v0.5.5/record.go:377
devops-alertcenter/internal/app/v1/logic.(*alertSender).send(0xc0001e1260)
/app/devops_alertcenter/internal/app/v1/logic/alert.go:141 +0xb65
devops-alertcenter/internal/app/v1/logic.GeneralAlert({0x1589160?, 0xc000304180}, 0xc000102150)
/app/devops_alertcenter/internal/app/v1/logic/general_alert.go:39 +0x268
devops-alertcenter/internal/app/v1/controller.(*GeneralAlertController).Alert(0xc0001e1340)
/app/devops_alertcenter/internal/app/v1/controller/general_alert.go:40 +0x12f
devops-alertcenter/internal/app/v1/controller.AlertDispatchController(0xc00035cc00)
/app/devops_alertcenter/internal/app/v1/controller/alert_dispatch.go:26 +0x14d
github.com/gofiber/fiber/v2.(*App).next(0xc0003b0f00, 0xc00035cc00)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/router.go:145 +0x1b2
github.com/gofiber/fiber/v2.(*Ctx).Next(0xc0003c08a0?)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/ctx.go:1030 +0x4d
github.com/gofiber/fiber/v2/middleware/logger.New.func3(0xc00035cc00)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/middleware/logger/logger.go:119 +0x316
github.com/gofiber/fiber/v2.(*Ctx).Next(0xc00057a330?)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/ctx.go:1027 +0x3d
github.com/gofiber/fiber/v2/middleware/cors.New.func1(0xc00035cc00)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/middleware/cors/cors.go:191 +0x326
github.com/gofiber/fiber/v2.(*Ctx).Next(0xc0000687d0?)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/ctx.go:1027 +0x3d
github.com/gofiber/fiber/v2/middleware/healthcheck.New.func1(0xc00035cc00)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/middleware/healthcheck/healthcheck.go:41 +0x154
github.com/gofiber/fiber/v2.(*Ctx).Next(0xc00057a4e0?)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/ctx.go:1027 +0x3d
devops-alertcenter/internal/app/server.StartHttpServer.func2(0xc00035cc00)
/app/devops_alertcenter/internal/app/server/httpserver.go:78 +0xaf
github.com/gofiber/fiber/v2.(*Ctx).Next(0xc00032a000?)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/ctx.go:1027 +0x3d
devops-alertcenter/internal/app/server.StartHttpServer.New.func6(0xb7ec20?)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/middleware/requestid/requestid.go:31 +0xe5
github.com/gofiber/fiber/v2.(*App).next(0xc0003b0f00, 0xc00035cc00)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/router.go:145 +0x1b2
github.com/gofiber/fiber/v2.(*App).handler(0xc0003b0f00, 0x4cb24f?)
/gopath/pkg/mod/github.com/gofiber/fiber/v2@v2.52.2/router.go:172 +0x78
github.com/valyala/fasthttp.(*Server).serveConn(0xc00036bc00, {0x158c0f0?, 0xc000482008})
/gopath/pkg/mod/github.com/valyala/fasthttp@v1.51.0/server.go:2359 +0x11d4
github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0003ad180, 0xc0003b4020)
/gopath/pkg/mod/github.com/valyala/fasthttp@v1.51.0/workerpool.go:224 +0xa4
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
/gopath/pkg/mod/github.com/valyala/fasthttp@v1.51.0/workerpool.go:196 +0x32
created by github.com/valyala/fasthttp.(*workerPool).getCh in goroutine 1
/gopath/pkg/mod/github.com/valyala/fasthttp@v1.51.0/workerpool.go:195 +0x1ab
/app/devops_alertcenter/internal/pkg/logger/logger.go:64 这个文件内容如下:
r.Fields[consts.RequestIDKeyName] = r.Ctx.Value(consts.RequestIDKeyName) // 第64行
// Setup 初始化日志
func Setup(cfg *config.ServiceConfig) {
var (
logSetting = cfg.LogSetting
rotation = rotatefile.RotateTime(logSetting.Rotation)
backupNum = logSetting.BackupNum
backupTime = logSetting.BackupTime
maxSize = logSetting.MaxSize * rotatefile.OneMByte
errorHandler *handler.SyncCloseHandler
normalHandler *handler.SyncCloseHandler
errorFilename = fmt.Sprintf("%s.error%s", logSetting.ServiceLogFilename, logSetting.LogFilenamePostfix)
errorFilepath = path.Join(logSetting.LogDir, errorFilename)
normalFilename = fmt.Sprintf("%s.info%s", logSetting.ServiceLogFilename, logSetting.LogFilenamePostfix)
normalFilepath = path.Join(logSetting.LogDir, normalFilename)
textFormatter *slog.TextFormatter
commonConfigs = []handler.ConfigFn{
handler.WithBackupNum(backupNum), handler.WithBackupTime(backupTime),
handler.WithMaxSize(maxSize), handler.WithBuffSize(0),
}
errorConfigs = []handler.ConfigFn{
handler.WithLogLevels(slog.DangerLevels),
}
normalConfigs = []handler.ConfigFn{
handler.WithLogLevels(slog.NormalLevels),
}
)
errorConfigs = append(errorConfigs, commonConfigs...)
normalConfigs = append(normalConfigs, commonConfigs...)
textFormatter = slog.NewTextFormatter(LogRecordTemplate).Configure(func(f *slog.TextFormatter) {
f.TimeFormat = consts.LogDateTimeFormat // 自定义时间格式
})
// warning以上的级别写到一个文件
errorHandler = handler.MustRotateFile(errorFilepath, rotation, errorConfigs...)
errorHandler.SetFormatter(textFormatter)
// info以下的级别写到一个文件
normalHandler = handler.MustRotateFile(normalFilepath, rotation, normalConfigs...)
normalHandler.SetFormatter(textFormatter)
// 增加handler
slog.AddHandlers(errorHandler, normalHandler)
// 添加requestid
slog.AddProcessor(slog.ProcessorFunc(func(r *slog.Record) {
r.Fields[consts.RequestIDKeyName] = r.Ctx.Value(consts.RequestIDKeyName) // 第64行
}))
// 禁用console输出,默认是启用的
slog.SetLogLevel(slog.PanicLevel)
}
可以使用下面这个方法替代 r.Fields["requestid"] = r.Ctx.Value("requestid")
更保险,里面会做检查:
// L.AddProcessor(slog.ProcessorFunc(func(r *slog.Record) {
// r.Fields["requestid"] = r.Ctx.Value("requestid")
// }))
L.AddProcessor(slog.AppendCtxKeys("requestid"))