[修改]日志中的堆栈信息无换行问题
This commit is contained in:
parent
815b181a0c
commit
2a380347c6
|
@ -26,4 +26,5 @@ output/
|
||||||
|
|
||||||
# Go workspace file
|
# Go workspace file
|
||||||
/go.work.sum
|
/go.work.sum
|
||||||
/pom.xml
|
/pom.xml
|
||||||
|
/bj-rtsts-server
|
||||||
|
|
|
@ -36,7 +36,11 @@ func InitSlog() {
|
||||||
|
|
||||||
if logging.Stdout {
|
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,
|
Level: level,
|
||||||
AddSource: false,
|
AddSource: false,
|
||||||
})))
|
})))
|
||||||
|
@ -50,7 +54,11 @@ func InitSlog() {
|
||||||
LocalTime: true, // 日志备份使用本地时间
|
LocalTime: true, // 日志备份使用本地时间
|
||||||
Compress: logging.Compress, // 是否压缩日志
|
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,
|
Level: level,
|
||||||
AddSource: false,
|
AddSource: false,
|
||||||
})))
|
})))
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -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")
|
||||||
|
}
|
||||||
|
}
|
|
@ -122,11 +122,7 @@ func customRecoveryWithSlog(logger *slog.Logger, stack bool, recovery gin.Recove
|
||||||
}
|
}
|
||||||
|
|
||||||
if stack {
|
if stack {
|
||||||
logger.Error("请求处理Panic异常",
|
logger.Error("请求处理Panic异常", "error", err, "stack", string(debug.Stack()))
|
||||||
"error", err,
|
|
||||||
"stack", string(debug.Stack()),
|
|
||||||
)
|
|
||||||
debug.PrintStack()
|
|
||||||
} else {
|
} else {
|
||||||
logger.Error("请求处理Panic异常",
|
logger.Error("请求处理Panic异常",
|
||||||
"error", err,
|
"error", err,
|
||||||
|
|
Loading…
Reference in New Issue