mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-22 15:59:26 +00:00
log: use sync map
This commit is contained in:
parent
64773bf6bc
commit
4fb7b3a24e
1 changed files with 20 additions and 28 deletions
|
|
@ -21,7 +21,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"maps"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -42,18 +41,17 @@ type GlogHandler struct {
|
||||||
level atomic.Int32 // Current log level, atomically accessible
|
level atomic.Int32 // Current log level, atomically accessible
|
||||||
override atomic.Bool // Flag whether overrides are used, atomically accessible
|
override atomic.Bool // Flag whether overrides are used, atomically accessible
|
||||||
|
|
||||||
patterns []pattern // Current list of patterns to override with
|
patterns []pattern // Current list of patterns to override with
|
||||||
siteCache map[uintptr]slog.Level // Cache of callsite pattern evaluations
|
siteCache sync.Map // Cache of callsite pattern evaluations, maps uintptr -> slog.Level
|
||||||
location string // file:line location where to do a stackdump at
|
location string // file:line location where to do a stackdump at
|
||||||
lock sync.RWMutex // Lock protecting the override pattern list
|
lock sync.RWMutex // Lock protecting the override pattern list
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGlogHandler creates a new log handler with filtering functionality similar
|
// NewGlogHandler creates a new log handler with filtering functionality similar
|
||||||
// to Google's glog logger. The returned handler implements Handler.
|
// to Google's glog logger. The returned handler implements Handler.
|
||||||
func NewGlogHandler(h slog.Handler) *GlogHandler {
|
func NewGlogHandler(h slog.Handler) *GlogHandler {
|
||||||
return &GlogHandler{
|
return &GlogHandler{
|
||||||
origin: h,
|
origin: h,
|
||||||
siteCache: make(map[uintptr]slog.Level),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +67,7 @@ type pattern struct {
|
||||||
func (h *GlogHandler) Verbosity(level slog.Level) {
|
func (h *GlogHandler) Verbosity(level slog.Level) {
|
||||||
h.level.Store(int32(level))
|
h.level.Store(int32(level))
|
||||||
// clear the cache to make sure the verbosity is applied correctly.
|
// clear the cache to make sure the verbosity is applied correctly.
|
||||||
h.siteCache = make(map[uintptr]slog.Level)
|
h.siteCache.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vmodule sets the glog verbosity pattern.
|
// Vmodule sets the glog verbosity pattern.
|
||||||
|
|
@ -133,10 +131,9 @@ func (h *GlogHandler) Vmodule(ruleset string) error {
|
||||||
}
|
}
|
||||||
// Swap out the vmodule pattern for the new filter system
|
// Swap out the vmodule pattern for the new filter system
|
||||||
h.lock.Lock()
|
h.lock.Lock()
|
||||||
defer h.lock.Unlock()
|
|
||||||
|
|
||||||
h.patterns = filter
|
h.patterns = filter
|
||||||
h.siteCache = make(map[uintptr]slog.Level)
|
h.lock.Unlock()
|
||||||
|
h.siteCache.Clear()
|
||||||
h.override.Store(len(filter) != 0)
|
h.override.Store(len(filter) != 0)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -152,18 +149,15 @@ func (h *GlogHandler) Enabled(ctx context.Context, lvl slog.Level) bool {
|
||||||
// WithAttrs implements slog.Handler, returning a new Handler whose attributes
|
// WithAttrs implements slog.Handler, returning a new Handler whose attributes
|
||||||
// consist of both the receiver's attributes and the arguments.
|
// consist of both the receiver's attributes and the arguments.
|
||||||
func (h *GlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
func (h *GlogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||||
|
patterns := []pattern{}
|
||||||
h.lock.RLock()
|
h.lock.RLock()
|
||||||
siteCache := maps.Clone(h.siteCache)
|
patterns = append(patterns, h.patterns...)
|
||||||
h.lock.RUnlock()
|
h.lock.RUnlock()
|
||||||
|
|
||||||
patterns := []pattern{}
|
|
||||||
patterns = append(patterns, h.patterns...)
|
|
||||||
|
|
||||||
res := GlogHandler{
|
res := GlogHandler{
|
||||||
origin: h.origin.WithAttrs(attrs),
|
origin: h.origin.WithAttrs(attrs),
|
||||||
patterns: patterns,
|
patterns: patterns,
|
||||||
siteCache: siteCache,
|
location: h.location,
|
||||||
location: h.location,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.level.Store(h.level.Load())
|
res.level.Store(h.level.Load())
|
||||||
|
|
@ -183,30 +177,28 @@ func (h *GlogHandler) WithGroup(name string) slog.Handler {
|
||||||
// local and backtrace filters, finally emitting it if either allow it through.
|
// local and backtrace filters, finally emitting it if either allow it through.
|
||||||
func (h *GlogHandler) Handle(_ context.Context, r slog.Record) error {
|
func (h *GlogHandler) Handle(_ context.Context, r slog.Record) error {
|
||||||
// Check callsite cache for previously calculated log levels
|
// Check callsite cache for previously calculated log levels
|
||||||
h.lock.RLock()
|
lvl, ok := h.siteCache.Load(r.PC)
|
||||||
lvl, ok := h.siteCache[r.PC]
|
|
||||||
h.lock.RUnlock()
|
|
||||||
|
|
||||||
// If we didn't cache the callsite yet, calculate it
|
// If we didn't cache the callsite yet, calculate it
|
||||||
if !ok {
|
if !ok {
|
||||||
h.lock.Lock()
|
|
||||||
|
|
||||||
fs := runtime.CallersFrames([]uintptr{r.PC})
|
fs := runtime.CallersFrames([]uintptr{r.PC})
|
||||||
frame, _ := fs.Next()
|
frame, _ := fs.Next()
|
||||||
|
|
||||||
|
h.lock.RLock()
|
||||||
for _, rule := range h.patterns {
|
for _, rule := range h.patterns {
|
||||||
if rule.pattern.MatchString(fmt.Sprintf("+%s", frame.File)) {
|
if rule.pattern.MatchString(fmt.Sprintf("+%s", frame.File)) {
|
||||||
h.siteCache[r.PC], lvl, ok = rule.level, rule.level, true
|
h.siteCache.Store(r.PC, rule.level)
|
||||||
|
lvl, ok = rule.level, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
h.lock.RUnlock()
|
||||||
// If no rule matched, use the default log lvl
|
// If no rule matched, use the default log lvl
|
||||||
if !ok {
|
if !ok {
|
||||||
lvl = slog.Level(h.level.Load())
|
lvl = slog.Level(h.level.Load())
|
||||||
h.siteCache[r.PC] = lvl
|
h.siteCache.Store(r.PC, lvl)
|
||||||
}
|
}
|
||||||
h.lock.Unlock()
|
|
||||||
}
|
}
|
||||||
if lvl <= r.Level {
|
if lvl.(slog.Level) <= r.Level {
|
||||||
return h.origin.Handle(context.Background(), r)
|
return h.origin.Handle(context.Background(), r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue