Skip to content
/ slogmw Public

Middleware for the go standard library log/slog package

License

Notifications You must be signed in to change notification settings

zknill/slogmw

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go log/slog middleware

The slogmw package makes it easier to use the standard library log/slog package.

Go 1.21 includes a new structured logger, but it's hard to modify to your specific logging requirements. This package provides middleware to make it easier to add, change, or edit fields of the standard library structured logger.

The slog package, and the slogmw package comes with two hooks:

  • slog.HandlerOptions has a ReplaceAttr function. We use slogwm.FormatChain(...) to create a chain of formatters that edit attributes using this hook.
  • slog.Handler. You can use slowmw.WrapHandler(...) to wrap a handler and edit the log events.

Examples

Format the time field of the log events:

opts := &slog.HandlerOptions{
  // Create a chain of slog formatters
  ReplaceAttr: slogmw.FormatChain(
    // pass the key to edit "slog.TimeKey" and 
    // the date time format to use "time.DateTime"
    slogmw.FormatTime(slog.TimeKey, time.DateTime)
  ),
}

slog.SetDefault(slog.NewJSONHandler(os.Stdout, opts))

Change the key of a log field:

opts := &slog.HandlerOptions{
  // Create a chain of slog formatters
  ReplaceAttr: slogmw.FormatChain(
    // The default log event message key is "msg"
    // this is exported as the constant slog.MessageKey.
    // Here we can change the msg key to "log". All
    // log events will print out the log field as "log"
    // and not "msg".
    slogmw.FormatKey(slog.MessageKey, "log")
  ),
}

slog.SetDefault(slog.NewJSONHandler(os.Stdout, opts))
slog.Info("hello world")

// Output: {"level": "INFO", "log": "hello world" ...trimmed}

Include a field from the context.Context in every log event:

// create a function that can extract the
// attributes from the context passed.
ctxValueFn := func(ctx context.Context) []slog.Attr {
  v := ctx.Value("userid").(string)
  return []slog.Attr{slog.String("user_id", v)}
}

h := slogmw.WrapHandler(
  // Pass the built in JSONHandler to be wrapped
  slog.NewJSONHandler(os.Stdout, opts),
  // Pass the IncludeContext middleware to extract
  // values from the context and include them as log fields.
  slogmw.IncludeContext(ctxValueFn),
)

slog.SetDefault(h)

// The context passed to InfoContext will be
// available to the function in slogmw.IncludeContext. 
// If just slog.Info(...) is called, the context will
// be context.Background()
slog.InfoContext(ctx, "hello world")

// Output: {"level": "INFO", "msg": "hello world", "user_id": "..."}

Include a static field in every log event:

h := slogmw.WrapHandler(
  // Pass the built in JSONHandler to be wrapped
  slog.NewJSONHandler(os.Stdout, opts),
  // Include env=prod in every log event
  slogmw.IncludeStatic(slog.String("env", "prod"))
)

slog.SetDefault(h)

slog.Info("hello world")
// Output: {"level": "INFO", "msg": "hello world", "env": "prod" .. trimmed}

More example usage can be found in the middleware_test.go file.

About

Middleware for the go standard library log/slog package

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages