Files
QSfera/Server/vendor/github.com/olekukonko/ll/lh/pipe.go
T
Курнат Андрей 2315f25754 Initial QSfera import
2026-06-07 10:20:04 +03:00

77 lines
2.4 KiB
Go

package lh
import (
"fmt"
"os"
"time"
"github.com/olekukonko/ll/lx"
)
// Pipe chains multiple handler wrappers together, applying them from left to right.
// The wrappers are composed such that the first wrapper in the list becomes
// the innermost layer, and the last wrapper becomes the outermost layer.
//
// Usage pattern: Pipe(baseHandler, wrapper1, wrapper2, wrapper3)
// Result: wrapper3(wrapper2(wrapper1(baseHandler)))
//
// This enables clean, declarative construction of handler middleware chains.
//
// Example - building a processing pipeline:
//
// base := lx.NewJSONHandler(os.Stdout)
// handler := lh.Pipe(base,
// lh.NewDedup(2*time.Second), // 1. Deduplicate first
// lh.NewRateLimit(10, time.Second), // 2. Then rate limit
// )
// logger := lx.NewLogger(handler)
//
// In this example, logs flow: Dedup → RateLimit → AddTimestamp → JSONHandler
func Pipe(h lx.Handler, wraps ...lx.Wrap) lx.Handler {
for _, w := range wraps {
if w != nil {
h = w(h)
}
}
return h
}
// PipeDedup returns a wrapper that applies deduplication to the handler.
func PipeDedup(ttl time.Duration, opts ...DedupOpt[lx.Handler]) lx.Wrap {
return func(next lx.Handler) lx.Handler {
return NewDedup(next, ttl, opts...)
}
}
// PipeBuffer returns a wrapper that applies buffering to the handler.
func PipeBuffer(opts ...BufferingOpt) lx.Wrap {
return func(next lx.Handler) lx.Handler {
return NewBuffered(next, opts...)
}
}
// PipeRotate returns a wrapper that applies log rotation.
// Ideally, the 'next' handler should be one that writes to a file (like TextHandler or JSONHandler).
//
// If the underlying handler does not implement lx.HandlerOutputter (cannot change output destination),
// or if rotation initialization fails, this will log a warning to stderr and return the
// original handler unmodified to prevent application crashes.
func PipeRotate(maxSizeBytes int64, src RotateSource) lx.Wrap {
return func(next lx.Handler) lx.Handler {
// Attempt to cast to HandlerOutputter (Handler + Outputter interface)
h, ok := next.(lx.HandlerOutputter)
if !ok {
fmt.Fprintf(os.Stderr, "ll/lh: PipeRotate skipped - handler does not implement SetOutput(io.Writer)\n")
return next
}
// Initialize the rotating handler
r, err := NewRotating(h, maxSizeBytes, src)
if err != nil {
fmt.Fprintf(os.Stderr, "ll/lh: PipeRotate initialization failed: %v\n", err)
return next
}
return r
}
}