summaryrefslogtreecommitdiffstats
path: root/src/go/logger/handler.go
blob: 40282ead6040b3a3fc845e343332403f44e74a11 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package logger

import (
	"context"
	"log/slog"
	"os"
	"runtime"
	"strings"

	"github.com/lmittmann/tint"
)

func newTextHandler() slog.Handler {
	return slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
		Level: Level.lvl,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			switch a.Key {
			case slog.TimeKey:
				if isJournal {
					return slog.Attr{}
				}
			case slog.LevelKey:
				lvl := a.Value.Any().(slog.Level)
				s, ok := customLevels[lvl]
				if !ok {
					s = lvl.String()
				}
				return slog.String(a.Key, strings.ToLower(s))
			}
			return a
		},
	})
}

func newTerminalHandler() slog.Handler {
	return tint.NewHandler(os.Stderr, &tint.Options{
		AddSource: true,
		Level:     Level.lvl,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			switch a.Key {
			case slog.TimeKey:
				return slog.Attr{}
			case slog.SourceKey:
				if !Level.Enabled(slog.LevelDebug) {
					return slog.Attr{}
				}
			case slog.LevelKey:
				lvl := a.Value.Any().(slog.Level)
				if s, ok := customLevelsTerm[lvl]; ok {
					return slog.String(a.Key, s)
				}
			}
			return a
		},
	})
}

func withCallDepth(depth int, sh slog.Handler) slog.Handler {
	if v, ok := sh.(*callDepthHandler); ok {
		sh = v.sh
	}
	return &callDepthHandler{depth: depth, sh: sh}
}

type callDepthHandler struct {
	depth int
	sh    slog.Handler
}

func (h *callDepthHandler) Enabled(ctx context.Context, level slog.Level) bool {
	return h.sh.Enabled(ctx, level)
}

func (h *callDepthHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
	return withCallDepth(h.depth, h.sh.WithAttrs(attrs))
}

func (h *callDepthHandler) WithGroup(name string) slog.Handler {
	return withCallDepth(h.depth, h.sh.WithGroup(name))
}

func (h *callDepthHandler) Handle(ctx context.Context, r slog.Record) error {
	// https://pkg.go.dev/log/slog#example-package-Wrapping
	var pcs [1]uintptr
	// skip Callers and this function
	runtime.Callers(h.depth+2, pcs[:])
	r.PC = pcs[0]

	return h.sh.Handle(ctx, r)
}