feat(logger): create slogx for slog extension

Co-authored-by: Gaze <gazenw@users.noreply.github.com>
This commit is contained in:
Gaze
2024-04-10 04:39:52 +07:00
parent 2dc3ae7561
commit eff202c7fe
7 changed files with 98 additions and 15 deletions

View File

@@ -4,6 +4,8 @@ import (
"context"
"log/slog"
"os"
"github.com/gaze-network/indexer-network/pkg/logger/slogx"
)
type loggerKey struct{}
@@ -57,7 +59,7 @@ func WarnContext(ctx context.Context, msg string, args ...any) {
// ErrorContext logs at [LevelError] from logger in the given context.
func ErrorContext(ctx context.Context, msg string, err error, args ...any) {
log(ctx, FromContext(ctx), slog.LevelError, msg, append(args, AttrError(err))...)
log(ctx, FromContext(ctx), slog.LevelError, msg, append(args, slogx.Error(err))...)
}
// PanicContext logs at [LevelPanic] and then panics from logger in the given context.

View File

@@ -8,21 +8,14 @@ import (
"strings"
"github.com/cockroachdb/errors/errbase"
"github.com/gaze-network/indexer-network/pkg/logger/slogx"
)
// AttrError returns an attribute with error key.
func AttrError(err error) slog.Attr {
if err == nil {
return slog.Attr{}
}
return slog.Any(ErrorKey, err)
}
func middlewareError() middleware {
return func(next handleFunc) handleFunc {
return func(ctx context.Context, rec slog.Record) error {
rec.Attrs(func(attr slog.Attr) bool {
if attr.Key == ErrorKey || attr.Key == "err" {
if attr.Key == slogx.ErrorKey || attr.Key == "err" {
err := attr.Value.Any()
if err, ok := err.(error); ok && err != nil {
rec.AddAttrs(slog.String("error_verbose", fmt.Sprintf("%+v", err)))

View File

@@ -8,6 +8,8 @@ import (
"runtime"
"strings"
"time"
"github.com/gaze-network/indexer-network/pkg/logger/slogx"
)
const (
@@ -85,7 +87,7 @@ func Warn(msg string, args ...any) {
// Error logs at [LevelError] with an error.
func Error(msg string, err error, args ...any) {
log(context.Background(), logger, slog.LevelError, msg, append(args, AttrError(err))...)
log(context.Background(), logger, slog.LevelError, msg, append(args, slogx.Error(err))...)
}
// Panic logs at [LevelPanic] and then panics.

View File

@@ -3,6 +3,8 @@ package logger
import (
"log/slog"
"os"
"github.com/gaze-network/indexer-network/pkg/logger/slogx"
)
func NewGCPHandler(opts *slog.HandlerOptions) slog.Handler {
@@ -19,11 +21,11 @@ func NewGCPHandler(opts *slog.HandlerOptions) slog.Handler {
// GCPAttrReplacer replaces the default attribute keys with the GCP logging attribute keys.
func GCPAttrReplacer(groups []string, attr slog.Attr) slog.Attr {
switch attr.Key {
case MessageKey:
case slogx.MessageKey:
attr.Key = "message"
case SourceKey:
case slogx.SourceKey:
attr.Key = "logging.googleapis.com/sourceLocation"
case LevelKey:
case slogx.LevelKey:
attr.Key = "severity"
lvl, ok := attr.Value.Any().(slog.Level)
if ok {

79
pkg/logger/slogx/attr.go Normal file
View File

@@ -0,0 +1,79 @@
package slogx
import (
"fmt"
"log/slog"
"time"
)
// Any returns an slog.Attr for the supplied value.
// See [AnyValue] for how values are treated.
func Any(key string, value any) slog.Attr {
return slog.Any(key, value)
}
// Group returns an slog.Attr for a Group [Value].
// The first argument is the key; the remaining arguments
// are converted to Attrs as in [Logger.Log].
//
// Use Group to collect several key-value pairs under a single
// key on a log line, or as the result of LogValue
// in order to log a single value as multiple Attrs.
func Group(key string, args ...any) slog.Attr {
return slog.Group(key, args...)
}
// Error returns an slog.Attr for an error value.
func Error(err error) slog.Attr {
if err == nil {
return slog.Attr{}
}
return slog.Any(ErrorKey, err)
}
// String returns an slog.Attr for a string value.
func String(key, value string) slog.Attr {
return slog.String(key, value)
}
// Stringer returns an slog.Attr for a fmt.Stringer value.
func Stringer(key string, value fmt.Stringer) slog.Attr {
return slog.String(key, value.String())
}
// Int64 returns an slog.Attr for an int64.
func Int64(key string, value int64) slog.Attr {
return slog.Int64(key, value)
}
// Int converts an int to an int64 and returns
// an slog.Attr with that value.
func Int(key string, value int) slog.Attr {
return slog.Int64(key, int64(value))
}
// Uint64 returns an slog.Attr for a uint64.
func Uint64(key string, v uint64) slog.Attr {
return slog.Uint64(key, v)
}
// Float64 returns an slog.Attr for a floating-point number.
func Float64(key string, v float64) slog.Attr {
return slog.Float64(key, v)
}
// Bool returns an slog.Attr for a bool.
func Bool(key string, v bool) slog.Attr {
return slog.Bool(key, v)
}
// Time returns an slog.Attr for a [time.Time].
// It discards the monotonic portion.
func Time(key string, v time.Time) slog.Attr {
return slog.Time(key, v)
}
// Duration returns an slog.Attr for a [time.Duration].
func Duration(key string, v time.Duration) slog.Attr {
return slog.Duration(key, v)
}

View File

@@ -1,4 +1,4 @@
package logger
package slogx
import "log/slog"

View File

@@ -0,0 +1,5 @@
/*
slogx is extension of slog package and logger package.
It provides additional attributes and helper functions for logging.
*/
package slogx