1 // recfile -- GNU recutils'es recfiles parser on pure Go
2 // Copyright (C) 2020-2024 Sergey Matveev <stargrave@stargrave.org>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, version 3 of the License.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program. If not, see <http://www.gnu.org/licenses/>.
26 "go.cypherpunks.ru/recfile"
29 type RecfileHandler struct {
40 func NewRecfileHandler(
43 levelKey, msgKey, timeKey string,
45 return &RecfileHandler{
55 func (h *RecfileHandler) Enabled(ctx context.Context, level slog.Level) bool {
56 return level >= h.Level
59 func (h *RecfileHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
60 return &RecfileHandler{
66 attrs: append(h.attrs, attrs...),
72 func (h *RecfileHandler) WithGroup(name string) slog.Handler {
73 neu := RecfileHandler{
80 group: h.group + name + "_",
86 func writeValue(w *recfile.Writer, group string, attr slog.Attr) (err error) {
87 if attr.Value.Kind() == slog.KindAny {
88 multiline, ok := attr.Value.Any().([]string)
90 if len(multiline) > 0 {
91 _, err = w.WriteFieldMultiline(group+attr.Key, multiline)
97 _, err = w.WriteFields(recfile.Field{
98 Name: group + attr.Key,
99 Value: attr.Value.String(),
104 func (h *RecfileHandler) Handle(ctx context.Context, rec slog.Record) (err error) {
106 w := recfile.NewWriter(&b)
107 _, err = w.RecordStart()
111 var fields []recfile.Field
112 if h.LevelKey != "" {
113 fields = append(fields, recfile.Field{
115 Value: rec.Level.String(),
119 fields = append(fields, recfile.Field{
121 Value: rec.Time.UTC().Format(time.RFC3339Nano),
124 fields = append(fields, recfile.Field{Name: h.MsgKey, Value: rec.Message})
125 _, err = w.WriteFields(fields...)
129 for _, attr := range h.attrs {
130 writeValue(w, h.group, attr)
132 rec.Attrs(func(attr slog.Attr) bool { return writeValue(w, h.group, attr) == nil })
134 n, err := h.W.Write(b.Bytes())