multi.go

v0.2.0
Doc Versions Source
1
package scribe
2
3
import (
4
	"context"
5
	"errors"
6
	"log/slog"
7
)
8
9
// MultiHandler fans out log records to multiple handlers.
10
type MultiHandler struct {
11
	handlers []slog.Handler
12
}
13
14
// NewMultiHandler creates a handler that writes to all given handlers.
15
func NewMultiHandler(handlers ...slog.Handler) *MultiHandler {
16
	return &MultiHandler{handlers: handlers}
17
}
18
19
// Enabled implements slog.Handler.
20
// Returns true if any inner handler is enabled for the level.
21
func (h *MultiHandler) Enabled(ctx context.Context, level slog.Level) bool {
22
	for _, handler := range h.handlers {
23
		if handler.Enabled(ctx, level) {
24
			return true
25
		}
26
	}
27
	return false
28
}
29
30
// Handle implements slog.Handler.
31
// Writes to all enabled handlers, collecting any errors.
32
func (h *MultiHandler) Handle(ctx context.Context, r slog.Record) error {
33
	var errs []error
34
	for _, handler := range h.handlers {
35
		if handler.Enabled(ctx, r.Level) {
36
			if err := handler.Handle(ctx, r); err != nil {
37
				errs = append(errs, err)
38
			}
39
		}
40
	}
41
	return errors.Join(errs...)
42
}
43
44
// WithAttrs implements slog.Handler.
45
func (h *MultiHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
46
	handlers := make([]slog.Handler, len(h.handlers))
47
	for i, handler := range h.handlers {
48
		handlers[i] = handler.WithAttrs(attrs)
49
	}
50
	return &MultiHandler{handlers: handlers}
51
}
52
53
// WithGroup implements slog.Handler.
54
func (h *MultiHandler) WithGroup(name string) slog.Handler {
55
	if name == "" {
56
		return h
57
	}
58
	handlers := make([]slog.Handler, len(h.handlers))
59
	for i, handler := range h.handlers {
60
		handlers[i] = handler.WithGroup(name)
61
	}
62
	return &MultiHandler{handlers: handlers}
63
}
64

Source Files