68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
package lh
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/cespare/xxhash/v2"
|
|
"github.com/olekukonko/ll/lx"
|
|
)
|
|
|
|
// rightPad pads a string with spaces on the right to reach the specified length.
|
|
// Returns the original string if it's already at or exceeds the target length.
|
|
// Uses strings.Builder for efficient memory allocation.
|
|
func rightPad(str string, length int) string {
|
|
if len(str) >= length {
|
|
return str
|
|
}
|
|
var sb strings.Builder
|
|
sb.Grow(length)
|
|
sb.WriteString(str)
|
|
sb.WriteString(strings.Repeat(" ", length-len(str)))
|
|
return sb.String()
|
|
}
|
|
|
|
var dedupBufPool = sync.Pool{
|
|
New: func() any { return new(bytes.Buffer) },
|
|
}
|
|
|
|
// defaultDedupKey generates a deduplication key from log level and message.
|
|
// Uses FNV-1a hash for speed and good distribution. Override with WithDedupKeyFunc
|
|
// to include additional fields like namespace, caller, or structured fields.
|
|
func defaultDedupKey(e *lx.Entry) uint64 {
|
|
h := xxhash.New()
|
|
|
|
_, _ = h.Write([]byte(e.Level.String()))
|
|
_, _ = h.Write([]byte{0})
|
|
_, _ = h.Write([]byte(e.Message))
|
|
_, _ = h.Write([]byte{0})
|
|
_, _ = h.Write([]byte(e.Namespace))
|
|
_, _ = h.Write([]byte{0})
|
|
|
|
if len(e.Fields) > 0 {
|
|
m := e.Fields.Map()
|
|
keys := make([]string, 0, len(m))
|
|
for k := range m {
|
|
keys = append(keys, k)
|
|
}
|
|
sort.Strings(keys)
|
|
|
|
buf := dedupBufPool.Get().(*bytes.Buffer)
|
|
buf.Reset()
|
|
defer dedupBufPool.Put(buf)
|
|
|
|
for _, k := range keys {
|
|
fmt.Fprint(buf, k)
|
|
buf.WriteByte('=')
|
|
fmt.Fprint(buf, m[k])
|
|
buf.WriteByte(0)
|
|
}
|
|
_, _ = h.Write(buf.Bytes())
|
|
}
|
|
|
|
return h.Sum64()
|
|
}
|