-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add filtering to logger (#15212)
- Loading branch information
1 parent
abd4ac0
commit ea8c76e
Showing
35 changed files
with
285 additions
and
188 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,84 @@ | ||
package log | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/rs/zerolog" | ||
) | ||
|
||
// 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 | ||
|
||
const defaultLogLevelKey = "*" | ||
|
||
// 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", "info") | ||
func ParseLogLevel(lvl string, defaultLogLevelValue string) (func(key, level string) bool, error) { | ||
return func(key, level string) bool { return true }, nil | ||
// ParseLogLevel("consensus:debug,mempool:debug,*:error") | ||
// | ||
// This function attemps 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]string) | ||
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) | ||
} | ||
|
||
if _, err := zerolog.ParseLevel(level); err != nil { | ||
return nil, fmt.Errorf("invalid log level %s in log level list %s", level, list) | ||
} | ||
|
||
filterMap[module] = level | ||
} | ||
|
||
filterFunc := func(key, lvl string) bool { | ||
level, ok := filterMap[key] | ||
if !ok { // no level filter for this key | ||
// check if there is a default level filter | ||
level, ok = filterMap[defaultLogLevelKey] | ||
if !ok { | ||
return false | ||
} | ||
} | ||
|
||
zllvl, err := zerolog.ParseLevel(lvl) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
zllevel, err := zerolog.ParseLevel(level) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
return zllvl < zllevel | ||
} | ||
|
||
return filterFunc, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package log_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"cosmossdk.io/log" | ||
"gotest.tools/v3/assert" | ||
) | ||
|
||
func TestParseLogLevel(t *testing.T) { | ||
_, err := log.ParseLogLevel("") | ||
assert.Error(t, err, "empty log level") | ||
|
||
level := "consensus:foo,mempool:debug,*:error" | ||
_, err = log.ParseLogLevel(level) | ||
assert.Error(t, err, "invalid log level foo in log level list [consensus:foo mempool:debug *:error]") | ||
|
||
level = "consensus:debug,mempool:debug,*:error" | ||
filter, err := log.ParseLogLevel(level) | ||
assert.NilError(t, err) | ||
assert.Assert(t, filter != nil) | ||
|
||
assert.Assert(t, !filter("consensus", "debug")) | ||
assert.Assert(t, !filter("consensus", "info")) | ||
assert.Assert(t, !filter("consensus", "error")) | ||
assert.Assert(t, !filter("mempool", "debug")) | ||
assert.Assert(t, !filter("mempool", "info")) | ||
assert.Assert(t, !filter("mempool", "error")) | ||
assert.Assert(t, !filter("state", "error")) | ||
assert.Assert(t, !filter("server", "panic")) | ||
|
||
assert.Assert(t, filter("server", "debug")) | ||
assert.Assert(t, filter("state", "debug")) | ||
assert.Assert(t, filter("state", "info")) | ||
|
||
level = "error" | ||
filter, err = log.ParseLogLevel(level) | ||
assert.NilError(t, err) | ||
assert.Assert(t, filter != nil) | ||
|
||
assert.Assert(t, !filter("state", "error")) | ||
assert.Assert(t, !filter("consensus", "error")) | ||
|
||
assert.Assert(t, filter("consensus", "debug")) | ||
assert.Assert(t, filter("consensus", "info")) | ||
assert.Assert(t, filter("state", "debug")) | ||
} |
Oops, something went wrong.