build: move log level parse code and add new leveled sub logger interface
This commit is contained in:
parent
e64493fe5b
commit
3ea74c4362
105
build/log.go
105
build/log.go
@ -1,7 +1,9 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/btcsuite/btclog"
|
"github.com/btcsuite/btclog"
|
||||||
)
|
)
|
||||||
@ -93,3 +95,106 @@ func NewSubLogger(subsystem string,
|
|||||||
// For any other configurations, we'll disable logging.
|
// For any other configurations, we'll disable logging.
|
||||||
return btclog.Disabled
|
return btclog.Disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubLoggers is a type that holds a map of subsystem loggers keyed by their
|
||||||
|
// subsystem name.
|
||||||
|
type SubLoggers map[string]btclog.Logger
|
||||||
|
|
||||||
|
// LeveledSubLogger provides the ability to retrieve the subsystem loggers of
|
||||||
|
// a logger and set their log levels individually or all at once.
|
||||||
|
type LeveledSubLogger interface {
|
||||||
|
// SubLoggers returns the map of all registered subsystem loggers.
|
||||||
|
SubLoggers() SubLoggers
|
||||||
|
|
||||||
|
// SupportedSubsystems returns a slice of strings containing the names
|
||||||
|
// of the supported subsystems. Should ideally correspond to the keys
|
||||||
|
// of the subsystem logger map and be sorted.
|
||||||
|
SupportedSubsystems() []string
|
||||||
|
|
||||||
|
// SetLogLevel assigns an individual subsystem logger a new log level.
|
||||||
|
SetLogLevel(subsystemID string, logLevel string)
|
||||||
|
|
||||||
|
// SetLogLevels assigns all subsystem loggers the same new log level.
|
||||||
|
SetLogLevels(logLevel string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseAndSetDebugLevels attempts to parse the specified debug level and set
|
||||||
|
// the levels accordingly on the given logger. An appropriate error is returned
|
||||||
|
// if anything is invalid.
|
||||||
|
func ParseAndSetDebugLevels(level string, logger LeveledSubLogger) error {
|
||||||
|
// When the specified string doesn't have any delimiters, treat it as
|
||||||
|
// the log level for all subsystems.
|
||||||
|
if !strings.Contains(level, ",") && !strings.Contains(level, "=") {
|
||||||
|
// Validate debug log level.
|
||||||
|
if !validLogLevel(level) {
|
||||||
|
str := "the specified debug level [%v] is invalid"
|
||||||
|
return fmt.Errorf(str, level)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change the logging level for all subsystems.
|
||||||
|
logger.SetLogLevels(level)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the specified string into subsystem/level pairs while detecting
|
||||||
|
// issues and update the log levels accordingly.
|
||||||
|
for _, logLevelPair := range strings.Split(level, ",") {
|
||||||
|
if !strings.Contains(logLevelPair, "=") {
|
||||||
|
str := "the specified debug level contains an " +
|
||||||
|
"invalid subsystem/level pair [%v]"
|
||||||
|
return fmt.Errorf(str, logLevelPair)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract the specified subsystem and log level.
|
||||||
|
fields := strings.Split(logLevelPair, "=")
|
||||||
|
if len(fields) != 2 {
|
||||||
|
str := "the specified debug level has an invalid " +
|
||||||
|
"format [%v] -- use format subsystem1=level1," +
|
||||||
|
"subsystem2=level2"
|
||||||
|
return fmt.Errorf(str, logLevelPair)
|
||||||
|
}
|
||||||
|
subsysID, logLevel := fields[0], fields[1]
|
||||||
|
subLoggers := logger.SubLoggers()
|
||||||
|
|
||||||
|
// Validate subsystem.
|
||||||
|
if _, exists := subLoggers[subsysID]; !exists {
|
||||||
|
str := "the specified subsystem [%v] is invalid -- " +
|
||||||
|
"supported subsystems are %v"
|
||||||
|
return fmt.Errorf(
|
||||||
|
str, subsysID, logger.SupportedSubsystems(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate log level.
|
||||||
|
if !validLogLevel(logLevel) {
|
||||||
|
str := "the specified debug level [%v] is invalid"
|
||||||
|
return fmt.Errorf(str, logLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.SetLogLevel(subsysID, logLevel)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validLogLevel returns whether or not logLevel is a valid debug log level.
|
||||||
|
func validLogLevel(logLevel string) bool {
|
||||||
|
switch logLevel {
|
||||||
|
case "trace":
|
||||||
|
fallthrough
|
||||||
|
case "debug":
|
||||||
|
fallthrough
|
||||||
|
case "info":
|
||||||
|
fallthrough
|
||||||
|
case "warn":
|
||||||
|
fallthrough
|
||||||
|
case "error":
|
||||||
|
fallthrough
|
||||||
|
case "critical":
|
||||||
|
fallthrough
|
||||||
|
case "off":
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
93
config.go
93
config.go
@ -14,7 +14,6 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sort"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -952,10 +951,11 @@ func loadConfig() (*config, error) {
|
|||||||
normalizeNetwork(activeNetParams.Name))
|
normalizeNetwork(activeNetParams.Name))
|
||||||
|
|
||||||
// Special show command to list supported subsystems and exit.
|
// Special show command to list supported subsystems and exit.
|
||||||
|
/*TODO(guggero) fix
|
||||||
if cfg.DebugLevel == "show" {
|
if cfg.DebugLevel == "show" {
|
||||||
fmt.Println("Supported subsystems", supportedSubsystems())
|
fmt.Println("Supported subsystems", supportedSubsystems())
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Initialize logging at the default logging level.
|
// Initialize logging at the default logging level.
|
||||||
initLogRotator(
|
initLogRotator(
|
||||||
@ -964,12 +964,13 @@ func loadConfig() (*config, error) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Parse, validate, and set debug log level(s).
|
// Parse, validate, and set debug log level(s).
|
||||||
|
/*TODO(guggero) fix
|
||||||
if err := parseAndSetDebugLevels(cfg.DebugLevel); err != nil {
|
if err := parseAndSetDebugLevels(cfg.DebugLevel); err != nil {
|
||||||
err := fmt.Errorf("%s: %v", funcName, err.Error())
|
err := fmt.Errorf("%s: %v", funcName, err.Error())
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
fmt.Fprintln(os.Stderr, usageMessage)
|
fmt.Fprintln(os.Stderr, usageMessage)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// At least one RPCListener is required. So listen on localhost per
|
// At least one RPCListener is required. So listen on localhost per
|
||||||
// default.
|
// default.
|
||||||
@ -1140,92 +1141,6 @@ func cleanAndExpandPath(path string) string {
|
|||||||
return filepath.Clean(os.ExpandEnv(path))
|
return filepath.Clean(os.ExpandEnv(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseAndSetDebugLevels attempts to parse the specified debug level and set
|
|
||||||
// the levels accordingly. An appropriate error is returned if anything is
|
|
||||||
// invalid.
|
|
||||||
func parseAndSetDebugLevels(debugLevel string) error {
|
|
||||||
// When the specified string doesn't have any delimiters, treat it as
|
|
||||||
// the log level for all subsystems.
|
|
||||||
if !strings.Contains(debugLevel, ",") && !strings.Contains(debugLevel, "=") {
|
|
||||||
// Validate debug log level.
|
|
||||||
if !validLogLevel(debugLevel) {
|
|
||||||
str := "The specified debug level [%v] is invalid"
|
|
||||||
return fmt.Errorf(str, debugLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Change the logging level for all subsystems.
|
|
||||||
setLogLevels(debugLevel)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split the specified string into subsystem/level pairs while detecting
|
|
||||||
// issues and update the log levels accordingly.
|
|
||||||
for _, logLevelPair := range strings.Split(debugLevel, ",") {
|
|
||||||
if !strings.Contains(logLevelPair, "=") {
|
|
||||||
str := "The specified debug level contains an invalid " +
|
|
||||||
"subsystem/level pair [%v]"
|
|
||||||
return fmt.Errorf(str, logLevelPair)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract the specified subsystem and log level.
|
|
||||||
fields := strings.Split(logLevelPair, "=")
|
|
||||||
subsysID, logLevel := fields[0], fields[1]
|
|
||||||
|
|
||||||
// Validate subsystem.
|
|
||||||
if _, exists := subsystemLoggers[subsysID]; !exists {
|
|
||||||
str := "The specified subsystem [%v] is invalid -- " +
|
|
||||||
"supported subsystems %v"
|
|
||||||
return fmt.Errorf(str, subsysID, supportedSubsystems())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate log level.
|
|
||||||
if !validLogLevel(logLevel) {
|
|
||||||
str := "The specified debug level [%v] is invalid"
|
|
||||||
return fmt.Errorf(str, logLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
setLogLevel(subsysID, logLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// validLogLevel returns whether or not logLevel is a valid debug log level.
|
|
||||||
func validLogLevel(logLevel string) bool {
|
|
||||||
switch logLevel {
|
|
||||||
case "trace":
|
|
||||||
fallthrough
|
|
||||||
case "debug":
|
|
||||||
fallthrough
|
|
||||||
case "info":
|
|
||||||
fallthrough
|
|
||||||
case "warn":
|
|
||||||
fallthrough
|
|
||||||
case "error":
|
|
||||||
fallthrough
|
|
||||||
case "critical":
|
|
||||||
fallthrough
|
|
||||||
case "off":
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// supportedSubsystems returns a sorted slice of the supported subsystems for
|
|
||||||
// logging purposes.
|
|
||||||
func supportedSubsystems() []string {
|
|
||||||
// Convert the subsystemLoggers map keys to a slice.
|
|
||||||
subsystems := make([]string, 0, len(subsystemLoggers))
|
|
||||||
for subsysID := range subsystemLoggers {
|
|
||||||
subsystems = append(subsystems, subsysID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the subsystems for stable display.
|
|
||||||
sort.Strings(subsystems)
|
|
||||||
return subsystems
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseRPCParams(cConfig *chainConfig, nodeConfig interface{}, net chainCode,
|
func parseRPCParams(cConfig *chainConfig, nodeConfig interface{}, net chainCode,
|
||||||
funcName string) error {
|
funcName string) error {
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@ -4343,7 +4342,7 @@ func (r *rpcServer) DebugLevel(ctx context.Context,
|
|||||||
// sub-systems.
|
// sub-systems.
|
||||||
if req.Show {
|
if req.Show {
|
||||||
return &lnrpc.DebugLevelResponse{
|
return &lnrpc.DebugLevelResponse{
|
||||||
SubSystems: strings.Join(supportedSubsystems(), " "),
|
SubSystems: "", //TODO(guggero) fix strings.Join(supportedSubsystems(), " "),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4351,9 +4350,11 @@ func (r *rpcServer) DebugLevel(ctx context.Context,
|
|||||||
|
|
||||||
// Otherwise, we'll attempt to set the logging level using the
|
// Otherwise, we'll attempt to set the logging level using the
|
||||||
// specified level spec.
|
// specified level spec.
|
||||||
|
/*TODO(guggero) fix
|
||||||
if err := parseAndSetDebugLevels(req.LevelSpec); err != nil {
|
if err := parseAndSetDebugLevels(req.LevelSpec); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return &lnrpc.DebugLevelResponse{}, nil
|
return &lnrpc.DebugLevelResponse{}, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user