github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/conf/logger/slog_handler.go (about) 1 package logger 2 3 import ( 4 "context" 5 "fmt" 6 "log/slog" 7 "os" 8 "path/filepath" 9 "runtime" 10 ) 11 12 func NewJsonHandler(skip int) *customJsonHandler { 13 return &customJsonHandler{ 14 skip: skip, 15 JSONHandler: slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ 16 AddSource: skip > 0, 17 Level: gLevel, 18 ReplaceAttr: CustomReplacer, 19 }), 20 } 21 } 22 23 type customJsonHandler struct { 24 skip int 25 *slog.JSONHandler 26 } 27 28 func (h *customJsonHandler) Handle(ctx context.Context, r slog.Record) error { 29 var pcs [1]uintptr 30 runtime.Callers(h.skip, pcs[:]) 31 r.PC = pcs[0] 32 return h.JSONHandler.Handle(ctx, r) 33 } 34 35 func (h *customJsonHandler) WithAttrs(attrs []slog.Attr) slog.Handler { 36 return &customJsonHandler{ 37 skip: h.skip, 38 JSONHandler: h.JSONHandler.WithAttrs(attrs).(*slog.JSONHandler), 39 } 40 } 41 42 func (h *customJsonHandler) WithGroup(group string) slog.Handler { 43 return &customJsonHandler{ 44 skip: h.skip, 45 JSONHandler: h.JSONHandler.WithGroup(group).(*slog.JSONHandler), 46 } 47 } 48 49 func (h *customJsonHandler) Enabled(_ context.Context, lv slog.Level) bool { 50 return lv >= gLevel 51 } 52 53 func NewTextHandler(skip int) *customTextHandler { 54 return &customTextHandler{ 55 skip: skip, 56 TextHandler: slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ 57 AddSource: skip > 0, 58 Level: gLevel, 59 ReplaceAttr: CustomReplacer, 60 }), 61 } 62 } 63 64 type customTextHandler struct { 65 skip int 66 *slog.TextHandler 67 } 68 69 func (h *customTextHandler) Handle(ctx context.Context, r slog.Record) error { 70 var pcs [1]uintptr 71 runtime.Callers(h.skip, pcs[:]) 72 r.PC = pcs[0] 73 return h.TextHandler.Handle(ctx, r) 74 } 75 76 func (h *customTextHandler) WithAttrs(attrs []slog.Attr) slog.Handler { 77 return &customTextHandler{ 78 skip: h.skip, 79 TextHandler: h.TextHandler.WithAttrs(attrs).(*slog.TextHandler), 80 } 81 } 82 83 func (h *customTextHandler) WithGroup(group string) slog.Handler { 84 return &customTextHandler{ 85 skip: h.skip, 86 TextHandler: h.TextHandler.WithGroup(group).(*slog.TextHandler), 87 } 88 } 89 90 func (h *customTextHandler) Enabled(_ context.Context, lv slog.Level) bool { 91 return lv >= gLevel 92 } 93 94 func CustomReplacer(groups []string, a slog.Attr) slog.Attr { 95 // time format 96 v := a.Value 97 if a.Value.Kind() == slog.KindTime { 98 a.Value = slog.StringValue(v.Time().Format("20060102-150405.000Z0700")) 99 } 100 101 // replace time key format 102 if a.Key == slog.TimeKey { 103 a.Key = "@ts" 104 return a 105 } 106 107 // replace level key 108 if a.Key == slog.LevelKey { 109 val := "" 110 switch v := a.Value.Any().(slog.Level); v { 111 case slog.LevelDebug: 112 val = "deb" 113 case slog.LevelInfo: 114 val = "inf" 115 case slog.LevelWarn: 116 val = "wrn" 117 default: 118 val = "err" 119 } 120 return slog.String("@lv", val) 121 } 122 123 // replace stack info 124 if a.Key == slog.SourceKey { 125 s := a.Value.Any().(*slog.Source) 126 s.File = filepath.Base(s.File) 127 return slog.String("@src", fmt.Sprintf("%s:%d", s.File, s.Line)) 128 } 129 130 return a 131 }