11 "go.cypherpunks.ru/recfile"
14 type RecfileHandler struct {
25 func NewRecfileHandler(
28 levelKey, msgKey, timeKey string,
30 return &RecfileHandler{
40 func (h *RecfileHandler) Enabled(ctx context.Context, level slog.Level) bool {
41 return level >= h.Level
44 func (h *RecfileHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
45 return &RecfileHandler{
51 attrs: append(h.attrs, attrs...),
57 func (h *RecfileHandler) WithGroup(name string) slog.Handler {
58 neu := RecfileHandler{
65 group: h.group + name + "_",
71 func writeValue(w *recfile.Writer, group string, attr slog.Attr) (err error) {
72 if attr.Value.Kind() == slog.KindAny {
73 multiline, ok := attr.Value.Any().([]string)
75 if len(multiline) > 0 {
76 _, err = w.WriteFieldMultiline(group+attr.Key, multiline)
82 _, err = w.WriteFields(recfile.Field{
83 Name: group + attr.Key,
84 Value: attr.Value.String(),
89 func (h *RecfileHandler) Handle(ctx context.Context, rec slog.Record) (err error) {
91 w := recfile.NewWriter(&b)
92 _, err = w.RecordStart()
96 var fields []recfile.Field
98 fields = append(fields, recfile.Field{
100 Value: rec.Level.String(),
104 fields = append(fields, recfile.Field{
106 Value: rec.Time.UTC().Format(time.RFC3339Nano),
109 fields = append(fields, recfile.Field{Name: h.MsgKey, Value: rec.Message})
110 _, err = w.WriteFields(fields...)
114 for _, attr := range h.attrs {
115 writeValue(w, h.group, attr)
117 rec.Attrs(func(attr slog.Attr) bool { return writeValue(w, h.group, attr) == nil })
119 n, err := h.W.Write(b.Bytes())