Skip to content

Commit

Permalink
custom field order
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffry-luqman committed Sep 25, 2023
1 parent 4e3e17d commit c7a4818
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 36 deletions.
81 changes: 50 additions & 31 deletions zlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"log/slog"
"net/http"
"slices"

"github.com/mattn/go-colorable"
)
Expand All @@ -26,6 +27,16 @@ var (
KeyMethod = "method"
KeyPath = "path"
KeyDelimiter = "="
FieldOrder = []string{
slog.LevelKey,
slog.TimeKey,
KeyStatus,
KeyDuration,
KeyMethod,
KeyPath,
slog.SourceKey,
slog.MessageKey,
}
)

// Format attributes for some keys, you can override this with your own preferences.
Expand Down Expand Up @@ -90,25 +101,39 @@ func (h *logHandler) WithGroup(name string) slog.Handler {
return &logHandler{sh: h.sh.WithGroup(name)}
}
func (h *logHandler) Handle(ctx context.Context, r slog.Record) error {
attrs := []slog.Attr{}
fields := map[string]string{}
level := r.Level.String()
statusCode := ""
duration := ""
method := ""
path := ""
switch r.Level {
case slog.LevelDebug:
level = Fmt(fmt.Sprintf("%6s", level), FmtLevelDebug...)
level = Fmt(fmt.Sprintf("%-6s", level), FmtLevelDebug...)
case slog.LevelInfo:
level = Fmt(fmt.Sprintf("%6s", level), FmtLevelInfo...)
level = Fmt(fmt.Sprintf("%-6s", level), FmtLevelInfo...)
case slog.LevelWarn:
level = Fmt(fmt.Sprintf("%6s", level), FmtLevelWarn...)
level = Fmt(fmt.Sprintf("%-6s", level), FmtLevelWarn...)
case slog.LevelError:
level = Fmt(fmt.Sprintf("%6s", level), FmtLevelError...)
level = Fmt(fmt.Sprintf("%-6s", level), FmtLevelError...)
}
attrs := []slog.Attr{}
if slices.Contains(FieldOrder, slog.LevelKey) {
fields[slog.LevelKey] = level
} else {
attrs = append(attrs, slog.String(slog.LevelKey, level))
}
if slices.Contains(FieldOrder, slog.TimeKey) {
fields[slog.TimeKey] = Fmt(r.Time.Format(TimeFormat), FmtTime...)
} else {
attrs = append(attrs, slog.String(slog.TimeKey, Fmt(r.Time.Format(TimeFormat), FmtTime...)))
}
if slices.Contains(FieldOrder, slog.MessageKey) {
fields[slog.MessageKey] = Fmt(r.Message, FmtMessage...)
} else {
attrs = append(attrs, slog.String(slog.MessageKey, Fmt(r.Message, FmtMessage...)))
}
// fields[slog.SourceKey] = Fmt(r.Message, FmtMessage...) // todo

r.Attrs(func(a slog.Attr) bool {
if a.Key == KeyStatus {
statusCode = a.Value.String()
if a.Key == KeyStatus && slices.Contains(FieldOrder, a.Key) {
statusCode := a.Value.String()
if a.Value.Kind() == slog.KindInt64 {
code := a.Value.Int64()
if code >= http.StatusInternalServerError {
Expand All @@ -125,13 +150,15 @@ func (h *logHandler) Handle(ctx context.Context, r slog.Record) error {
statusCode = Fmt(statusCode, FgGreen)
}
}
} else if a.Key == KeyDuration {
duration = a.Value.String()
fields[KeyStatus] = level
} else if a.Key == KeyDuration && slices.Contains(FieldOrder, a.Key) {
duration := a.Value.String()
if a.Value.Kind() == slog.KindDuration {
duration = a.Value.Duration().String()
}
} else if a.Key == KeyMethod {
method = a.Value.String()
fields[KeyDuration] = Fmt(fmt.Sprintf("%12s", duration), FmtDuration...)
} else if a.Key == KeyMethod && slices.Contains(FieldOrder, a.Key) {
method := a.Value.String()
switch method {
case http.MethodGet:
method = Fmt(fmt.Sprintf("%7s", method), FmtMethodGet...)
Expand All @@ -146,30 +173,22 @@ func (h *logHandler) Handle(ctx context.Context, r slog.Record) error {
default:
method = Fmt(fmt.Sprintf("%7s", method), FmtMethodOther...)
}
} else if a.Key == KeyPath {
path = a.Value.String()
fields[KeyMethod] = method
} else if a.Key == KeyPath && slices.Contains(FieldOrder, a.Key) {
fields[KeyPath] = a.Value.String()
} else {
attrs = append(attrs, a)
}
return true
})

b := &bytes.Buffer{}
h.write(b, level, " ")
h.write(b, Fmt(r.Time.Format(TimeFormat), FmtTime...), " ")
if statusCode != "" {
h.write(b, statusCode, " ")
}
if duration != "" {
h.write(b, Fmt(fmt.Sprintf("%12s", duration), FmtDuration...), " ")
}
if method != "" {
h.write(b, method, " ")
}
if path != "" {
h.write(b, Fmt(path, FmtPath...), " ")
for _, key := range FieldOrder {
val, ok := fields[key]
if ok {
h.write(b, val, " ")
}
}
h.write(b, Fmt(r.Message, FmtMessage...), " ")
for _, a := range attrs {
h.write(b, Fmt(a.Key, FmtAttrKey...), Fmt(KeyDelimiter, FmtAttrDelimiter...), Fmt(a.Value.String(), FmtAttrValue...), " ")
}
Expand Down
10 changes: 5 additions & 5 deletions zlog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ func TestZlog(t *testing.T) {
}

l.Info("msg", "a", 1, "b", 2)
check([]byte{27, 91, 51, 50, 109, 32, 32, 73, 78, 70, 79, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 109, 115, 103, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 49, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 98, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 50, 27, 91, 48, 109, 32, 10})
check([]byte{27, 91, 51, 50, 109, 73, 78, 70, 79, 32, 32, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 109, 115, 103, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 49, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 98, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 50, 27, 91, 48, 109, 32, 10})

// By default, debug messages are not printed.
l.Debug("bg", slog.Int("a", 1), "b", 2)
check([]byte{})

l.Warn("w", slog.Duration("dur", 3*time.Second))
check([]byte{27, 91, 57, 51, 109, 32, 32, 87, 65, 82, 78, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 119, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 100, 117, 114, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 51, 115, 27, 91, 48, 109, 32, 10})
check([]byte{27, 91, 57, 51, 109, 87, 65, 82, 78, 32, 32, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 119, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 100, 117, 114, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 51, 115, 27, 91, 48, 109, 32, 10})

l.Error("bad", "a", 1)
check([]byte{27, 91, 57, 49, 109, 32, 69, 82, 82, 79, 82, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 98, 97, 100, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 49, 27, 91, 48, 109, 32, 10})
check([]byte{27, 91, 57, 49, 109, 69, 82, 82, 79, 82, 32, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 98, 97, 100, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 49, 27, 91, 48, 109, 32, 10})

l.Log(ctx, slog.LevelWarn+1, "w", slog.Int("a", 1), slog.String("b", "two"))
check([]byte{87, 65, 82, 78, 43, 49, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 119, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 49, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 98, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 116, 119, 111, 27, 91, 48, 109, 32, 10})
Expand All @@ -50,10 +50,10 @@ func TestZlog(t *testing.T) {
check([]byte{73, 78, 70, 79, 43, 49, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 97, 32, 98, 32, 99, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 49, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 98, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 116, 119, 111, 27, 91, 48, 109, 32, 10})

l.Info("info", "a", []slog.Attr{slog.Int("i", 1)})
check([]byte{27, 91, 51, 50, 109, 32, 32, 73, 78, 70, 79, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 105, 110, 102, 111, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 91, 105, 61, 49, 93, 27, 91, 48, 109, 32, 10})
check([]byte{27, 91, 51, 50, 109, 73, 78, 70, 79, 32, 32, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 105, 110, 102, 111, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 91, 105, 61, 49, 93, 27, 91, 48, 109, 32, 10})

l.Info("info", "a", slog.GroupValue(slog.Int("i", 1)))
check([]byte{27, 91, 51, 50, 109, 32, 32, 73, 78, 70, 79, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 105, 110, 102, 111, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 91, 105, 61, 49, 93, 27, 91, 48, 109, 32, 10})
check([]byte{27, 91, 51, 50, 109, 73, 78, 70, 79, 32, 32, 27, 91, 48, 109, 32, 27, 91, 57, 48, 109, 90, 27, 91, 48, 109, 32, 27, 91, 48, 109, 105, 110, 102, 111, 27, 91, 48, 109, 32, 27, 91, 51, 52, 109, 97, 27, 91, 48, 109, 27, 91, 57, 48, 109, 61, 27, 91, 48, 109, 27, 91, 51, 51, 109, 91, 105, 61, 49, 93, 27, 91, 48, 109, 32, 10})
}

// This is a simple benchmark. See the benchmarks subdirectory for more extensive ones.
Expand Down

0 comments on commit c7a4818

Please sign in to comment.