126 lines
2.2 KiB
Go
126 lines
2.2 KiB
Go
package log
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"log/slog"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type Handler struct {
|
|
mu sync.Mutex
|
|
w io.Writer
|
|
level slog.Level
|
|
attrs []slog.Attr
|
|
groups []string
|
|
}
|
|
|
|
func New(w io.Writer, level slog.Level) *Handler {
|
|
return &Handler{w: w, level: level}
|
|
}
|
|
|
|
func (h *Handler) Enabled(_ context.Context, l slog.Level) bool {
|
|
return l >= h.level
|
|
}
|
|
|
|
func (h *Handler) Handle(_ context.Context, r slog.Record) error {
|
|
h.mu.Lock()
|
|
defer h.mu.Unlock()
|
|
|
|
level := r.Level.String()
|
|
switch r.Level {
|
|
case slog.LevelDebug:
|
|
level = "DEBUG"
|
|
case slog.LevelInfo:
|
|
level = "INFO"
|
|
case slog.LevelWarn:
|
|
level = "WARN"
|
|
case slog.LevelError:
|
|
level = "ERROR"
|
|
}
|
|
|
|
_, file, line, ok := runtime.Caller(4)
|
|
if !ok {
|
|
file = "???"
|
|
}
|
|
short := file
|
|
for i := len(file) - 1; i > 0; i-- {
|
|
if file[i] == '/' {
|
|
short = file[i+1:]
|
|
break
|
|
}
|
|
}
|
|
|
|
t := r.Time.Format("2006-01-02 15:04:05.000")
|
|
|
|
var b strings.Builder
|
|
b.WriteString(fmt.Sprintf("[%s] [%s] [%s:%d]", level, t, short, line))
|
|
|
|
if len(h.groups) > 0 {
|
|
b.WriteString(" [" + strings.Join(h.groups, ".") + "]")
|
|
}
|
|
if r.Message != "" {
|
|
b.WriteString(" " + r.Message)
|
|
}
|
|
|
|
r.Attrs(func(a slog.Attr) bool {
|
|
b.WriteString(fmt.Sprintf(" %s=%v", a.Key, a.Value.Any()))
|
|
return true
|
|
})
|
|
for _, a := range h.attrs {
|
|
b.WriteString(fmt.Sprintf(" %s=%v", a.Key, a.Value.Any()))
|
|
}
|
|
|
|
b.WriteString("\n")
|
|
_, err := h.w.Write([]byte(b.String()))
|
|
return err
|
|
}
|
|
|
|
func (h *Handler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
|
if len(attrs) == 0 {
|
|
return h
|
|
}
|
|
h2 := h.clone()
|
|
h2.attrs = append(h2.attrs, attrs...)
|
|
return h2
|
|
}
|
|
|
|
func (h *Handler) WithGroup(name string) slog.Handler {
|
|
if name == "" {
|
|
return h
|
|
}
|
|
h2 := h.clone()
|
|
h2.groups = append(h2.groups, name)
|
|
return h2
|
|
}
|
|
|
|
func (h *Handler) clone() *Handler {
|
|
return &Handler{
|
|
w: h.w,
|
|
level: h.level,
|
|
attrs: append([]slog.Attr{}, h.attrs...),
|
|
groups: append([]string{}, h.groups...),
|
|
}
|
|
}
|
|
|
|
func Init(level string) {
|
|
var l slog.Level
|
|
switch strings.ToUpper(level) {
|
|
case "DEBUG":
|
|
l = slog.LevelDebug
|
|
case "INFO":
|
|
l = slog.LevelInfo
|
|
case "WARN":
|
|
l = slog.LevelWarn
|
|
case "ERROR":
|
|
l = slog.LevelError
|
|
default:
|
|
l = slog.LevelInfo
|
|
}
|
|
slog.SetDefault(slog.New(New(os.Stderr, l)))
|
|
}
|