feat(logz)!: promote to v1.0.0 — configurable io.Writer output destination

Add Writer io.Writer field to Options; when nil, defaults to os.Stdout (no
breaking change). Enables log capture in tests via the public API and supports
writing to files, multi-writers, or any io.Writer implementation in production.
All remaining roadmap items validated in production (xerrors enrichment
concurrency, WithFields merge semantics, Logger interface finality). API
committed as stable.
This commit is contained in:
2026-05-11 18:50:37 -06:00
parent 3667b92fab
commit 05c99f72ff
3 changed files with 41 additions and 18 deletions

17
logz.go
View File

@@ -3,6 +3,7 @@ package logz
import (
"context"
"errors"
"io"
"log/slog"
"os"
)
@@ -20,7 +21,7 @@ type errorWithContext interface {
}
// Options configures a Logger instance.
// The zero value is valid: INFO level, text output, no static args.
// The zero value is valid: INFO level, text output, os.Stdout, no static args.
type Options struct {
// Level is the minimum log level. Default: slog.LevelInfo (zero value).
Level slog.Level
@@ -28,6 +29,9 @@ type Options struct {
JSON bool
// StaticArgs are key-value pairs attached to every log record.
StaticArgs []any
// Writer is the output destination. Defaults to os.Stdout when nil.
// Accepts any io.Writer: *os.File, bytes.Buffer, io.MultiWriter, etc.
Writer io.Writer
}
// Logger is the interface for structured logging.
@@ -56,16 +60,17 @@ type slogLogger struct {
// New returns a new Logger configured by opts.
func New(opts Options) Logger {
handlerOpts := &slog.HandlerOptions{
Level: opts.Level,
AddSource: false,
w := opts.Writer
if w == nil {
w = os.Stdout
}
handlerOpts := &slog.HandlerOptions{Level: opts.Level}
var handler slog.Handler
if opts.JSON {
handler = slog.NewJSONHandler(os.Stdout, handlerOpts)
handler = slog.NewJSONHandler(w, handlerOpts)
} else {
handler = slog.NewTextHandler(os.Stdout, handlerOpts)
handler = slog.NewTextHandler(w, handlerOpts)
}
base := slog.New(handler)