64 lines
1.3 KiB
Go
64 lines
1.3 KiB
Go
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)
|
|
}
|