https://github.com/nickbryan/slogutil
A utility library for Go's log/slog package that provides a context aware and in-memory handler whilst handling deduplication of attributes.
https://github.com/nickbryan/slogutil
go golang golang-library golang-package logging
Last synced: 5 months ago
JSON representation
A utility library for Go's log/slog package that provides a context aware and in-memory handler whilst handling deduplication of attributes.
- Host: GitHub
- URL: https://github.com/nickbryan/slogutil
- Owner: nickbryan
- License: mit
- Created: 2024-11-24T08:09:57.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-11-20T19:35:20.000Z (7 months ago)
- Last Synced: 2025-11-20T21:15:43.474Z (7 months ago)
- Topics: go, golang, golang-library, golang-package, logging
- Language: Go
- Homepage:
- Size: 74.2 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# slogutil
Package `slogutil` provides enhanced logging capabilities for the standard library `log/slog` package, focusing on
context integration and testability.
[](https://github.com/nickbryan/slogutil/actions)
[](https://github.com/nickbryan/slogutil/actions)
[](https://goreportcard.com/report/nickbryan/slogutil)
[](https://github.com/nickbryan/slogutil/blob/master/LICENSE)
## Features
* **Context-Aware Logging:** Enriches log records with contextual information from `context.Context`:
* The `slogctx` sub-package provides a handler (`slogctx.Handler`) and an `Extractor` API to extract values from the context.
* Supports adding attributes to the root of the log context or appending them within the current log group.
* **Testability:** Enables easy testing of log output:
* Provides an in-memory handler (`slogmem`) to capture log records during tests, allowing for assertions and verification.
* **Attribute Consistency:** Provides consistent handling of log attributes:
* Deduplicates attributes with the same respecting groups. For example: `duplicate`, `duplicate#01`, `duplcate#02`.
## Quick Start
```go
package main
import (
"context"
"log/slog"
"github.com/nickbryan/slogutil"
"github.com/nickbryan/slogutil/slogctx"
)
func main() {
ctx := slogctx.WithAttrs(context.Background(), slog.String("my_appended_attribute", "my_appended_value"))
ctx = slogctx.WithRootAttrs(ctx, slog.String("my_root_attribute", "my_root_value"))
logger := slogutil.NewJSONLogger().WithGroup("my_group")
logger.InfoContext(ctx, "Info log message", slog.String("my_attribute", "my_value"))
// Output:
// {"time":"2024-11-29T10:27:41.460372Z","level":"INFO","source":{"function":"main.main","file":main.go","line":16},"msg":"Info log message","my_root_attribute":"my_root_value","my_group":{"my_attribute":"my_value","my_appended_attribute":"my_appended_value"}}
}
```
## Testing
`slogutil` provides an in-memory handler (`slogmem`) to capture log records, enabling you to test log output effectively:
```go
func TestThing(t *testing.T) {
ctx := slogctx.WithPrependAttrs(context.Background(), slog.String("prepend_attribute", "prepend_value"))
ctx = slogctx.WithAppendAttrs(ctx, slog.String("append_attribute", "append_value"))
logger, logs := slogutil.NewInMemoryLogger(slog.LevelDebug)
logger = logger.With(slog.Int("my_root_attribute", 123))
logger = logger.WithGroup("my_group")
logger.InfoContext(ctx, "Info log message", slog.String("my_grouped_attribute", "my_value"))
if ok, diff := logs.Contains(slogmem.RecordQuery{
Level: slog.LevelInfo,
Message: "Info log message",
Attrs: map[string]slog.Value{
"prepend_attribute": slog.StringValue("prepend_value"),
"my_root_attribute": slog.IntValue(123),
"my_group.my_grouped_attribute": slog.StringValue("my_value"),
"my_group.append_attribute": slog.StringValue("append_value"),
},
}); !ok {
t.Errorf("expected log not written, got: %s", diff)
}
}
```