cosmos-sdk/log/level.go
2025-02-13 16:23:25 -05:00

81 lines
2.0 KiB
Go

package log
import (
"errors"
"fmt"
"strings"
"github.com/rs/zerolog"
)
const defaultLogLevelKey = "*"
// FilterFunc is a function that returns true if the log level is filtered for the given key
// When the filter returns true, the log entry is discarded.
type FilterFunc func(key, level string) bool
// ParseLogLevel parses complex log level
// A comma-separated list of module:level pairs with an optional *:level pair
// (* means all other modules).
//
// Example:
// ParseLogLevel("consensus:debug,mempool:debug,*:error")
//
// This function attempts to keep the same behavior as the CometBFT ParseLogLevel
// However the level `none` is replaced by `disabled`.
func ParseLogLevel(levelStr string) (FilterFunc, error) {
if levelStr == "" {
return nil, errors.New("empty log level")
}
// prefix simple one word levels (e.g. "info") with "*"
l := levelStr
if !strings.Contains(l, ":") {
l = defaultLogLevelKey + ":" + l
}
// parse and validate the levels
filterMap := make(map[string]zerolog.Level)
list := strings.Split(l, ",")
for _, item := range list {
moduleAndLevel := strings.Split(item, ":")
if len(moduleAndLevel) != 2 {
return nil, fmt.Errorf("expected list in a form of \"module:level\" pairs, given pair %s, list %s", item, list)
}
module := moduleAndLevel[0]
level := moduleAndLevel[1]
if _, ok := filterMap[module]; ok {
return nil, fmt.Errorf("duplicate module %s in log level list %s", module, list)
}
zllevel, err := zerolog.ParseLevel(level)
if err != nil {
return nil, fmt.Errorf("invalid log level %s in log level list %s", level, list)
}
filterMap[module] = zllevel
}
filterFunc := func(key, lvl string) bool {
zllevel, ok := filterMap[key]
if !ok { // no level filter for this key
// check if there is a default level filter
zllevel, ok = filterMap[defaultLogLevelKey]
if !ok {
return false
}
}
zllvl, err := zerolog.ParseLevel(lvl)
if err != nil {
panic(err)
}
return zllvl < zllevel
}
return filterFunc, nil
}