Initial QSfera import
This commit is contained in:
+76
@@ -0,0 +1,76 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user