81 lines
2.0 KiB
Go
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
|
|
}
|