Skip to content

Commit

Permalink
refactor: change logger to only accept slog.Attrs
Browse files Browse the repository at this point in the history
Y'know, for performance. Logging is intense
  • Loading branch information
dmke committed Oct 28, 2024
1 parent 438953a commit 21628c6
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 38 deletions.
3 changes: 2 additions & 1 deletion service/middleware/logging.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package middleware

import (
"log/slog"
"net"
"net/http"

Expand Down Expand Up @@ -33,7 +34,7 @@ func WithLogging(log xlog.Logger) func(http.Handler) http.Handler {

next.ServeHTTP(rl, r)

logAttrs := []any{ // []slog.Attr
logAttrs := []slog.Attr{
RequestIDField(r.Context()),
xlog.String("method", r.Method),
xlog.Int("status", rl.status),
Expand Down
17 changes: 10 additions & 7 deletions xlog/discard.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package xlog

import "os"
import (
"log/slog"
"os"
)

type discard struct{}

Expand All @@ -13,9 +16,9 @@ func NewDiscard() Logger {
return &discard{}
}

func (*discard) Debug(msg string, args ...any) {}
func (*discard) Info(msg string, args ...any) {}
func (*discard) Warn(msg string, args ...any) {}
func (*discard) Error(msg string, args ...any) {}
func (*discard) Fatal(msg string, args ...any) { os.Exit(1) }
func (d *discard) With(args ...any) Logger { return d }
func (*discard) Debug(string, ...slog.Attr) {}
func (*discard) Info(string, ...slog.Attr) {}
func (*discard) Warn(string, ...slog.Attr) {}
func (*discard) Error(string, ...slog.Attr) {}
func (*discard) Fatal(string, ...slog.Attr) { os.Exit(1) }
func (d *discard) With(...slog.Attr) Logger { return d }
55 changes: 25 additions & 30 deletions xlog/log.go → xlog/xlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,30 @@ import (
// A Logger allows writing messages with various severities.
type Logger interface {
// Debug writes log messages with DEBUG severity.
Debug(msg string, args ...any)
Debug(msg string, a ...slog.Attr)
// Info writes log messages with INFO severity.
Info(msg string, args ...any)
Info(msg string, a ...slog.Attr)
// Warn writes log messages with WARN severity.
Warn(msg string, args ...any)
Warn(msg string, a ...slog.Attr)
// Error writes log messages with ERROR severity.
Error(msg string, args ...any)
Error(msg string, a ...slog.Attr)
// Fatal writes log messages with ERROR severity, and then
// exits the whole program.
Fatal(msg string, args ...any)
// With creates a child logger, and adds the given arguments
// to each child message output
With(args ...any) Logger
Fatal(msg string, a ...slog.Attr)
// With returns a Logger that includes the given attributes
// in each output operation.
With(a ...slog.Attr) Logger
}

type logger struct {
l *slog.Logger
// context holds the arguments received from With().
context []any
}

// New creates a new logger instance. By default, log messages are
// written to stdout, and the log level is INFO.
func New(opt ...Option) (Logger, error) {
opts := options{
output: os.Stdout,
handlerOpts: &slog.HandlerOptions{},
}

Expand Down Expand Up @@ -70,48 +71,42 @@ func New(opt ...Option) (Logger, error) {
}

// log creates a log record. It is called by Debug, Info, etc.
func (log *logger) log(level slog.Level, msg string, args ...any) {
func (log *logger) log(level slog.Level, msg string, a ...slog.Attr) {
if !log.l.Enabled(context.Background(), level) {
return
}
var pcs [1]uintptr
runtime.Callers(3, pcs[:]) // skip runtime.Callers, log, and our caller
r := slog.NewRecord(time.Now(), level, msg, pcs[0])
r.Add(log.context...)
r.Add(args...)
r.AddAttrs(a...)
_ = log.l.Handler().Handle(context.Background(), r)
}

func (log *logger) Debug(msg string, args ...any) {
log.log(slog.LevelDebug, msg, args...)
func (log *logger) Debug(msg string, a ...slog.Attr) {
log.log(slog.LevelDebug, msg, a...)
}

func (log *logger) Info(msg string, args ...any) {
log.log(slog.LevelInfo, msg, args...)
func (log *logger) Info(msg string, a ...slog.Attr) {
log.log(slog.LevelInfo, msg, a...)
}

func (log *logger) Warn(msg string, args ...any) {
log.log(slog.LevelWarn, msg, args...)
func (log *logger) Warn(msg string, a ...slog.Attr) {
log.log(slog.LevelWarn, msg, a...)
}

func (log *logger) Error(msg string, args ...any) {
log.log(slog.LevelError, msg, args...)
func (log *logger) Error(msg string, a ...slog.Attr) {
log.log(slog.LevelError, msg, a...)
}

// Fatal is the same as Error, but quits the program via os.Exit(1).
func (log *logger) Fatal(msg string, args ...any) {
log.log(slog.LevelError, msg, args...)
func (log *logger) Fatal(msg string, a ...slog.Attr) {
log.log(slog.LevelError, msg, a...)
os.Exit(1)
}

func (log *logger) With(args ...any) Logger {
context := make([]any, 0, len(log.context)+len(args))
context = append(context, log.context...)
context = append(context, args...)

func (log *logger) With(a ...slog.Attr) Logger {
return &logger{
l: log.l,
context: context,
l: slog.New(log.l.Handler().WithAttrs(a)),
}
}

Expand Down

0 comments on commit 21628c6

Please sign in to comment.