[修改]日志中的堆栈信息无换行问题

This commit is contained in:
thesai 2024-06-16 12:26:48 +08:00
parent 815b181a0c
commit 2a380347c6
5 changed files with 97 additions and 8 deletions

3
.gitignore vendored
View File

@ -26,4 +26,5 @@ output/
# Go workspace file
/go.work.sum
/pom.xml
/pom.xml
/bj-rtsts-server

View File

@ -36,7 +36,11 @@ func InitSlog() {
if logging.Stdout {
// 日志输出到控制台
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
//slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
// Level: level,
// AddSource: false,
//})))
slog.SetDefault(slog.New(newMyJsonHandler(os.Stdout, &slog.HandlerOptions{
Level: level,
AddSource: false,
})))
@ -50,7 +54,11 @@ func InitSlog() {
LocalTime: true, // 日志备份使用本地时间
Compress: logging.Compress, // 是否压缩日志
}
slog.SetDefault(slog.New(slog.NewJSONHandler(lumberJackLogger, &slog.HandlerOptions{
//slog.SetDefault(slog.New(slog.NewJSONHandler(lumberJackLogger, &slog.HandlerOptions{
// Level: level,
// AddSource: false,
//})))
slog.SetDefault(slog.New(newMyJsonHandler(lumberJackLogger, &slog.HandlerOptions{
Level: level,
AddSource: false,
})))

63
logger/my_json_handler.go Normal file
View File

@ -0,0 +1,63 @@
package logger
import (
"context"
"io"
"log/slog"
"sync"
)
type MyJsonHandler struct {
output io.Writer
mu sync.Mutex
jsonHandler slog.Handler
}
var stackChan = make(chan string, 100)
func newMyJsonHandler(output io.Writer, opts *slog.HandlerOptions) *MyJsonHandler {
if opts == nil {
opts = &slog.HandlerOptions{}
}
ra := opts.ReplaceAttr
opts.ReplaceAttr = func(groups []string, a slog.Attr) slog.Attr {
if a.Key == "stack" {
stackChan <- a.Value.String()
return slog.Attr{}
} else {
if ra != nil {
return ra(groups, a)
} else {
return a
}
}
}
return &MyJsonHandler{output: output, mu: sync.Mutex{}, jsonHandler: slog.NewJSONHandler(output, opts)}
}
func (s *MyJsonHandler) Enabled(ctx context.Context, level slog.Level) bool {
return s.jsonHandler.Enabled(ctx, level)
}
func (s *MyJsonHandler) Handle(ctx context.Context, record slog.Record) error {
err := s.jsonHandler.Handle(ctx, record)
if err != nil {
return err
}
select {
case stack := <-stackChan:
s.mu.Lock()
defer s.mu.Unlock()
_, err = s.output.Write([]byte(stack))
default:
}
return err
}
func (s *MyJsonHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
return s.jsonHandler.WithAttrs(attrs)
}
func (s *MyJsonHandler) WithGroup(name string) slog.Handler {
return s.jsonHandler.WithGroup(name)
}

View File

@ -0,0 +1,21 @@
package logger
import (
"log/slog"
"os"
"testing"
)
func BenchmarkMyJsonHandler_Handle(b *testing.B) {
for i := 0; i < b.N; i++ {
//slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
// AddSource: false,
// Level: nil,
//})))
slog.SetDefault(slog.New(newMyJsonHandler(os.Stdout, &slog.HandlerOptions{
AddSource: false,
Level: nil,
})))
slog.Info("这是一条日志", "error", "错误", "stack", "goroutine 10 [running]:\nruntime/debug.Stack()\n\tD:/develop/Go/go1.21.4/src/runtime/debug/stack.go:24 +0x6b\njoylink.club/bj-rtsts-server/starter.customRecoveryWithSlog.func1.1()\n\tD:/GoProject/rts-sim-testing-service/starter/init.go:126 +0x36f\npanic({0x1f0cb40?, 0x226fd50?})\n\tD:/develop/Go/go1.21.4/src/runtime/panic.go:920 +0x290\njoylink.club/bj-rtsts-server/api.createByProjectId(0xc001a06100)\n\tD:/GoProject/rts-sim-testing-service/api/simulation.go:91 +0x26\ngithub.com/gin-gonic/gin.(*Context).Next(0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174 +0x7a\njoylink.club/bj-rtsts-server/middleware.permissionMiddleware.func1(0xc001a06100)\n\tD:/GoProject/rts-sim-testing-service/middleware/auth.go:35 +0x178\ngithub.com/gin-gonic/gin.(*Context).Next(0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174 +0x7a\ngithub.com/appleboy/gin-jwt/v2.(*GinJWTMiddleware).middlewareImpl(0xc000504340, 0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/appleboy/gin-jwt/v2@v2.9.1/auth_jwt.go:462 +0x579\ngithub.com/appleboy/gin-jwt/v2.(*GinJWTMiddleware).MiddlewareFunc.func1(0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/appleboy/gin-jwt/v2@v2.9.1/auth_jwt.go:415 +0x26\ngithub.com/gin-gonic/gin.(*Context).Next(0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174 +0x7a\njoylink.club/bj-rtsts-server/starter.customRecoveryWithSlog.func1(0xc001a06100)\n\tD:/GoProject/rts-sim-testing-service/starter/init.go:135 +0xef\ngithub.com/gin-gonic/gin.(*Context).Next(0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174 +0x7a\ngithub.com/samber/slog-gin.NewWithConfig.func1(0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/samber/slog-gin@v1.1.0/middleware.go:70 +0x13f\ngithub.com/gin-gonic/gin.(*Context).Next(0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174 +0x7a\ngithub.com/gin-gonic/gin.(*Engine).handleHTTPRequest(0xc0004d51e0, 0xc001a06100)\n\tC:/Users/thesai/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:620 +0x427\ngithub.com/gin-gonic/gin.(*Engine).ServeHTTP(0xc0004d51e0, {0x227e480, 0xc00012aee0}, 0xc001a07100)\n\tC:/Users/thesai/go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:576 +0xbc\nnet/http.serverHandler.ServeHTTP({0xc0017f0960}, {0x227e480, 0xc00012aee0}, 0xc001a07100)\n\tD:/develop/Go/go1.21.4/src/net/http/server.go:2938 +0x257\nnet/http.(*conn).serve(0xc0019422d0, {0x2285b38, 0xc001982000})\n\tD:/develop/Go/go1.21.4/src/net/http/server.go:2009 +0x1a39\ncreated by net/http.(*Server).Serve in goroutine 1\n\tD:/develop/Go/go1.21.4/src/net/http/server.go:3086 +0xa25")
}
}

View File

@ -122,11 +122,7 @@ func customRecoveryWithSlog(logger *slog.Logger, stack bool, recovery gin.Recove
}
if stack {
logger.Error("请求处理Panic异常",
"error", err,
"stack", string(debug.Stack()),
)
debug.PrintStack()
logger.Error("请求处理Panic异常", "error", err, "stack", string(debug.Stack()))
} else {
logger.Error("请求处理Panic异常",
"error", err,