Merge pull request #4772 from halseth/log-levels-global-sub
build/log: support parsing global+subsystem levels
This commit is contained in:
commit
4587b6dbab
28
build/log.go
28
build/log.go
@ -122,24 +122,32 @@ type LeveledSubLogger interface {
|
|||||||
// the levels accordingly on the given logger. An appropriate error is returned
|
// the levels accordingly on the given logger. An appropriate error is returned
|
||||||
// if anything is invalid.
|
// if anything is invalid.
|
||||||
func ParseAndSetDebugLevels(level string, logger LeveledSubLogger) error {
|
func ParseAndSetDebugLevels(level string, logger LeveledSubLogger) error {
|
||||||
// When the specified string doesn't have any delimiters, treat it as
|
// Split at the delimiter.
|
||||||
// the log level for all subsystems.
|
levels := strings.Split(level, ",")
|
||||||
if !strings.Contains(level, ",") && !strings.Contains(level, "=") {
|
if len(levels) == 0 {
|
||||||
|
return fmt.Errorf("invalid log level: %v", level)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the first entry has no =, treat is as the log level for all
|
||||||
|
// subsystems.
|
||||||
|
globalLevel := levels[0]
|
||||||
|
if !strings.Contains(globalLevel, "=") {
|
||||||
// Validate debug log level.
|
// Validate debug log level.
|
||||||
if !validLogLevel(level) {
|
if !validLogLevel(globalLevel) {
|
||||||
str := "the specified debug level [%v] is invalid"
|
str := "the specified debug level [%v] is invalid"
|
||||||
return fmt.Errorf(str, level)
|
return fmt.Errorf(str, globalLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the logging level for all subsystems.
|
// Change the logging level for all subsystems.
|
||||||
logger.SetLogLevels(level)
|
logger.SetLogLevels(globalLevel)
|
||||||
|
|
||||||
return nil
|
// The rest will target specific subsystems.
|
||||||
|
levels = levels[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split the specified string into subsystem/level pairs while detecting
|
// Go through the subsystem/level pairs while detecting issues and
|
||||||
// issues and update the log levels accordingly.
|
// update the log levels accordingly.
|
||||||
for _, logLevelPair := range strings.Split(level, ",") {
|
for _, logLevelPair := range levels {
|
||||||
if !strings.Contains(logLevelPair, "=") {
|
if !strings.Contains(logLevelPair, "=") {
|
||||||
str := "the specified debug level contains an " +
|
str := "the specified debug level contains an " +
|
||||||
"invalid subsystem/level pair [%v]"
|
"invalid subsystem/level pair [%v]"
|
||||||
|
118
build/log_test.go
Normal file
118
build/log_test.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package build_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/btcsuite/btclog"
|
||||||
|
"github.com/lightningnetwork/lnd/build"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
type mockSubLogger struct {
|
||||||
|
globalLogLevel string
|
||||||
|
subLogLevels map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockSubLogger) SubLoggers() build.SubLoggers {
|
||||||
|
return build.SubLoggers{
|
||||||
|
"PEER": btclog.Disabled,
|
||||||
|
"SRVR": btclog.Disabled,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockSubLogger) SupportedSubsystems() []string {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockSubLogger) SetLogLevel(subsystemID string, logLevel string) {
|
||||||
|
m.subLogLevels[subsystemID] = logLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockSubLogger) SetLogLevels(logLevel string) {
|
||||||
|
m.globalLogLevel = logLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestParseAndSetDebugLevels tests tha we can properly set the log levels for
|
||||||
|
// all andspecified subsystems.
|
||||||
|
func TestParseAndSetDebugLevels(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
debugLevel string
|
||||||
|
expErr string
|
||||||
|
expGlobal string
|
||||||
|
expSubLevels map[string]string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty log level",
|
||||||
|
debugLevel: "",
|
||||||
|
expErr: "invalid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid global debug level",
|
||||||
|
debugLevel: "ddddddebug",
|
||||||
|
expErr: "invalid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "global debug level",
|
||||||
|
debugLevel: "debug",
|
||||||
|
expGlobal: "debug",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid global debug level#2",
|
||||||
|
debugLevel: "debug,info",
|
||||||
|
expErr: "invalid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid subsystem debug level",
|
||||||
|
debugLevel: "AAAA=debug",
|
||||||
|
expErr: "invalid",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid subsystem debug level",
|
||||||
|
debugLevel: "PEER=info,SRVR=debug",
|
||||||
|
expSubLevels: map[string]string{
|
||||||
|
"PEER": "info",
|
||||||
|
"SRVR": "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid global+subsystem debug level",
|
||||||
|
debugLevel: "trace,PEER=info,SRVR=debug",
|
||||||
|
expGlobal: "trace",
|
||||||
|
expSubLevels: map[string]string{
|
||||||
|
"PEER": "info",
|
||||||
|
"SRVR": "debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid global+subsystem debug level",
|
||||||
|
debugLevel: "PEER=info,debug,SRVR=debug",
|
||||||
|
expErr: "invalid",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range testCases {
|
||||||
|
test := test
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
m := &mockSubLogger{
|
||||||
|
subLogLevels: make(map[string]string),
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the subsystem map is empty, make and empty one to ensure
|
||||||
|
// the equal test later succeeds.
|
||||||
|
if len(test.expSubLevels) == 0 {
|
||||||
|
test.expSubLevels = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := build.ParseAndSetDebugLevels(test.debugLevel, m)
|
||||||
|
if test.expErr != "" {
|
||||||
|
require.Contains(t, err.Error(), test.expErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Equal(t, test.expGlobal, m.globalLogLevel)
|
||||||
|
require.Equal(t, test.expSubLevels, m.subLogLevels)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -216,7 +216,7 @@ type Config struct {
|
|||||||
MaxBackoff time.Duration `long:"maxbackoff" description:"Longest backoff when reconnecting to persistent peers. Valid time units are {s, m, h}."`
|
MaxBackoff time.Duration `long:"maxbackoff" description:"Longest backoff when reconnecting to persistent peers. Valid time units are {s, m, h}."`
|
||||||
ConnectionTimeout time.Duration `long:"connectiontimeout" description:"The timeout value for network connections. Valid time units are {ms, s, m, h}."`
|
ConnectionTimeout time.Duration `long:"connectiontimeout" description:"The timeout value for network connections. Valid time units are {ms, s, m, h}."`
|
||||||
|
|
||||||
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify <subsystem>=<level>,<subsystem2>=<level>,... to set the log level for individual subsystems -- Use show to list available subsystems"`
|
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify <global-level>,<subsystem>=<level>,<subsystem2>=<level>,... to set the log level for individual subsystems -- Use show to list available subsystems"`
|
||||||
|
|
||||||
CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
|
CPUProfile string `long:"cpuprofile" description:"Write CPU profile to the specified file"`
|
||||||
|
|
||||||
|
@ -193,10 +193,10 @@
|
|||||||
|
|
||||||
; Debug logging level.
|
; Debug logging level.
|
||||||
; Valid levels are {trace, debug, info, warn, error, critical}
|
; Valid levels are {trace, debug, info, warn, error, critical}
|
||||||
; You may also specify <subsystem>=<level>,<subsystem2>=<level>,... to set
|
; You may also specify <global-level>,<subsystem>=<level>,<subsystem2>=<level>,...
|
||||||
; log level for individual subsystems. Use lncli debuglevel --show to list
|
; to set log level for individual subsystems. Use lncli debuglevel --show to
|
||||||
; available subsystems.
|
; list available subsystems.
|
||||||
; debuglevel=info
|
; debuglevel=debug,PEER=info
|
||||||
|
|
||||||
; Write CPU profile to the specified file.
|
; Write CPU profile to the specified file.
|
||||||
; cpuprofile=
|
; cpuprofile=
|
||||||
|
Loading…
Reference in New Issue
Block a user