55 "fmt"
66 "log/slog"
77 "os"
8- "path/filepath "
8+ "runtime "
99 "strings"
10+ "time"
1011)
1112
1213const (
@@ -15,24 +16,30 @@ const (
1516 LevelPanic = slog .Level (255 )
1617)
1718
18- var (
19- levelNames = map [slog.Leveler ]string {
20- LevelTrace : "TRACE" ,
21- LevelFatal : "FATAL" ,
22- }
23- )
24-
2519type (
2620 Logger struct {
2721 * slog.Logger
2822 }
2923
3024 HandlerOptions struct {
3125 * slog.HandlerOptions
32- ShowTime bool
33- ShortenSourcePath bool
26+ ShowTime bool
27+ SourceMode SourceMode
28+ }
29+
30+ SourceMode string
31+ )
3432
35- sourceRelPath string
33+ const (
34+ SourceModeFile SourceMode = "file"
35+ SourceModeShort SourceMode = "short"
36+ SourceModeFull SourceMode = "full"
37+ )
38+
39+ var (
40+ levelNames = map [slog.Leveler ]string {
41+ LevelTrace : "TRACE" ,
42+ LevelFatal : "FATAL" ,
3643 }
3744)
3845
@@ -42,9 +49,6 @@ func NewHandlerOptions(handler *slog.HandlerOptions) *HandlerOptions {
4249 }
4350
4451 ret := & HandlerOptions {HandlerOptions : handler }
45- if val , err := os .Executable (); err == nil {
46- ret .sourceRelPath = strings .TrimRight (filepath .Dir (val ), "/" ) + "/"
47- }
4852
4953 if handler .ReplaceAttr != nil {
5054 handler .ReplaceAttr = NewReplaceAttr (ret , handler .ReplaceAttr )
@@ -70,18 +74,17 @@ func NewReplaceAttr(handler *HandlerOptions, callback func(groups []string, a sl
7074 return slog.Attr {}
7175 }
7276 case slog .SourceKey :
73- if handler .ShortenSourcePath {
77+ switch handler .SourceMode {
78+ case SourceModeFile :
7479 if src , ok := a .Value .Any ().(* slog.Source ); ok {
75- shortPath := ""
76- if v , ok := strings .CutPrefix (src .File , handler .sourceRelPath ); ok {
77- shortPath = v
78- } else {
79- fullPath := src .File
80- seps := strings .Split (fullPath , "/" )
81- shortPath += seps [len (seps )- 1 ]
82- }
83- shortPath += fmt .Sprintf (":%d" , src .Line )
84- a .Value = slog .StringValue (shortPath )
80+ a .Value = slog .StringValue (fmt .Sprintf ("%s:%d" , src .File , src .Line ))
81+ }
82+ case SourceModeShort :
83+ if src , ok := a .Value .Any ().(* slog.Source ); ok {
84+ fullPath := src .File
85+ seps := strings .Split (fullPath , "/" )
86+ shortPath := seps [len (seps )- 1 ]
87+ a .Value = slog .StringValue (fmt .Sprintf ("%s:%d" , shortPath , src .Line ))
8588 }
8689 }
8790 }
@@ -95,17 +98,40 @@ func New(handler slog.Handler) *Logger {
9598 Logger : slog .New (handler ),
9699 }
97100}
101+
98102func (l * Logger ) Trace (msg string , fields ... any ) {
99- l .Log (context .Background (), LevelTrace , msg , fields ... )
103+ if ! l .Enabled (context .Background (), LevelTrace ) {
104+ return
105+ }
106+
107+ var pcs [1 ]uintptr
108+ runtime .Callers (2 , pcs [:]) // skip [Callers, Trace]
109+ r := slog .NewRecord (time .Now (), LevelTrace , msg , pcs [0 ])
110+ _ = l .Handler ().Handle (context .Background (), r )
100111}
101112
102113func (l * Logger ) Fatal (msg string , fields ... any ) {
103- l .Log (context .Background (), LevelFatal , msg , fields ... )
114+ if ! l .Enabled (context .Background (), LevelFatal ) {
115+ return
116+ }
117+
118+ var pcs [1 ]uintptr
119+ runtime .Callers (2 , pcs [:]) // skip [Callers, Fatal]
120+ r := slog .NewRecord (time .Now (), LevelFatal , msg , pcs [0 ])
121+ _ = l .Handler ().Handle (context .Background (), r )
122+
104123 os .Exit (1 )
105124}
106125
107126func (l * Logger ) Panic (msg string , fields ... any ) {
108- l .Log (context .Background (), LevelPanic , msg , fields ... )
127+ if ! l .Enabled (context .Background (), LevelPanic ) {
128+ return
129+ }
130+
131+ var pcs [1 ]uintptr
132+ runtime .Callers (2 , pcs [:]) // skip [Callers, Panic]
133+ r := slog .NewRecord (time .Now (), LevelPanic , msg , pcs [0 ])
134+ _ = l .Handler ().Handle (context .Background (), r )
109135 panic (msg )
110136}
111137
0 commit comments