feat(logz): initial stable release v0.9.0
Structured logger backed by log/slog with request-context enrichment, extra-field context helpers, and duck-typed automatic error enrichment. What's included: - `Logger` interface with Debug / Info / Warn / Error / With / WithContext; `New(Options)` constructor writing to os.Stdout - `WithRequestID` / `GetRequestID` and `WithField` / `WithFields` context helpers — package owns both context keys - Automatic error_code and context-field enrichment in Logger.Error via duck-typed errorWithCode / errorWithContext interfaces (no xerrors import) Tested-via: todo-api POC integration Reviewed-against: docs/adr/
This commit is contained in:
43
context.go
Normal file
43
context.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package logz
|
||||
|
||||
import "context"
|
||||
|
||||
// ctxRequestIDKey is the context key for the request correlation ID.
|
||||
type ctxRequestIDKey struct{}
|
||||
|
||||
// ctxExtraFieldsKey is the context key for arbitrary logging fields.
|
||||
type ctxExtraFieldsKey struct{}
|
||||
|
||||
// WithRequestID adds a request correlation ID to the context.
|
||||
func WithRequestID(ctx context.Context, id string) context.Context {
|
||||
return context.WithValue(ctx, ctxRequestIDKey{}, id)
|
||||
}
|
||||
|
||||
// GetRequestID retrieves the correlation ID from the context.
|
||||
// Returns "" if not present or if ctx is nil.
|
||||
func GetRequestID(ctx context.Context) string {
|
||||
if ctx == nil {
|
||||
return ""
|
||||
}
|
||||
id, _ := ctx.Value(ctxRequestIDKey{}).(string)
|
||||
return id
|
||||
}
|
||||
|
||||
// WithField adds a single key-value pair to the context for logging.
|
||||
func WithField(ctx context.Context, key string, value any) context.Context {
|
||||
return WithFields(ctx, map[string]any{key: value})
|
||||
}
|
||||
|
||||
// WithFields adds multiple key-value pairs to the context for logging.
|
||||
// Merges with any existing fields — does not overwrite the whole map.
|
||||
func WithFields(ctx context.Context, fields map[string]any) context.Context {
|
||||
existing, _ := ctx.Value(ctxExtraFieldsKey{}).(map[string]any)
|
||||
newMap := make(map[string]any, len(existing)+len(fields))
|
||||
for k, v := range existing {
|
||||
newMap[k] = v
|
||||
}
|
||||
for k, v := range fields {
|
||||
newMap[k] = v
|
||||
}
|
||||
return context.WithValue(ctx, ctxExtraFieldsKey{}, newMap)
|
||||
}
|
||||
Reference in New Issue
Block a user