rts-sim-testing-service/logger/my_json_handler.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)
}