feat: add --log-level support for manager and scheduler (#4146)

Signed-off-by: Aaron Wang <aaron.wang@maiscrm.com>
Co-authored-by: Aaron Wang <aaron.wang@maiscrm.com>
This commit is contained in:
Aaron Wang 2025-06-24 11:53:31 +08:00 committed by GitHub
parent 917348d419
commit 1ba7014527
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 75 additions and 33 deletions

View File

@ -26,6 +26,7 @@ scheduler:
# when enabled, pprof will be enabled,
verbose: true
log-level: debug
console: false
# current host info used for scheduler

View File

@ -19,6 +19,7 @@ package base
type Options struct {
Console bool `yaml:"console" mapstructure:"console"`
Verbose bool `yaml:"verbose" mapstructure:"verbose"`
LogLevel string `yaml:"log-level" mapstructure:"log-level"`
PProfPort int `yaml:"pprof-port" mapstructure:"pprof-port"`
Tracing TracingConfig `yaml:"tracing" mapstructure:"tracing"`
}

View File

@ -72,6 +72,7 @@ func InitCommandAndConfig(cmd *cobra.Command, useConfigFile bool, config any) {
flags := cmd.PersistentFlags()
flags.Bool("console", false, "whether logger output records to the stdout")
flags.Bool("verbose", false, "whether logger use debug level")
flags.String("log-level", "", "use specific log level(debug, info, warn, error), take precedence over verbose flag")
flags.Int("pprof-port", -1, "listen port for pprof, 0 represents random port")
flags.String("config", "", fmt.Sprintf("the path of configuration file with yaml extension name, default is %s, it can also be set by env var: %s", filepath.Join(dfpath.DefaultConfigDir, rootName+".yaml"), strings.ToUpper(rootName+"_config")))

View File

@ -142,7 +142,7 @@ func runDfcacheSubcmd(ctx context.Context, cmdName string, args []string) error
MaxBackups: dfcacheConfig.LogMaxBackups}
// Initialize logger
if err := logger.InitDfcache(dfcacheConfig.Console, d.LogDir(), rotateConfig); err != nil {
if err := logger.InitDfcache(dfcacheConfig.Verbose, dfcacheConfig.LogLevel, d.LogDir(), rotateConfig); err != nil {
return fmt.Errorf("init client dfcache logger: %w", err)
}
logger.Infof("version:\n%s", version.Version())

View File

@ -47,8 +47,8 @@ var (
var daemonCmd = &cobra.Command{
Use: "daemon",
Short: "start the client daemon of dragonfly",
Long: `client daemon is mainly responsible for transmitting blocks between peers
and putting the completed file into the specified target path. at the same time,
Long: `client daemon is mainly responsible for transmitting blocks between peers
and putting the completed file into the specified target path. at the same time,
it supports container engine, wget and other downloading tools through proxy function.`,
Args: cobra.NoArgs,
DisableAutoGenTag: true,
@ -80,7 +80,7 @@ it supports container engine, wget and other downloading tools through proxy fun
MaxBackups: cfg.LogMaxBackups}
// Initialize logger
if err := logger.InitDaemon(cfg.Verbose, cfg.Console, d.LogDir(), rotateConfig); err != nil {
if err := logger.InitDaemon(cfg.Verbose, cfg.LogLevel, cfg.Console, d.LogDir(), rotateConfig); err != nil {
return fmt.Errorf("init client daemon logger: %w", err)
}
logger.RedirectStdoutAndStderr(cfg.Console, path.Join(d.LogDir(), types.DaemonName))

View File

@ -94,7 +94,7 @@ var rootCmd = &cobra.Command{
MaxBackups: dfgetConfig.LogMaxBackups}
// Initialize logger
if err := logger.InitDfget(dfgetConfig.Verbose, dfgetConfig.Console, d.LogDir(), rotateConfig); err != nil {
if err := logger.InitDfget(dfgetConfig.Verbose, dfgetConfig.LogLevel, dfgetConfig.Console, d.LogDir(), rotateConfig); err != nil {
return fmt.Errorf("init client dfget logger: %w", err)
}

View File

@ -41,7 +41,7 @@ var (
var rootCmd = &cobra.Command{
Use: "manager",
Short: "The central manager of dragonfly.",
Long: `manager is a long-running process and is mainly responsible
Long: `manager is a long-running process and is mainly responsible
for managing schedulers and seed peers, offering http apis and portal, etc.`,
Args: cobra.NoArgs,
DisableAutoGenTag: true,
@ -72,7 +72,7 @@ for managing schedulers and seed peers, offering http apis and portal, etc.`,
MaxBackups: cfg.Server.LogMaxBackups}
// Initialize logger.
if err := logger.InitManager(cfg.Verbose, cfg.Console, d.LogDir(), rotateConfig); err != nil {
if err := logger.InitManager(cfg.Verbose, cfg.LogLevel, cfg.Console, d.LogDir(), rotateConfig); err != nil {
return fmt.Errorf("init manager logger: %w", err)
}
logger.RedirectStdoutAndStderr(cfg.Console, path.Join(d.LogDir(), types.ManagerName))

View File

@ -41,7 +41,7 @@ var (
var rootCmd = &cobra.Command{
Use: "scheduler",
Short: "the scheduler of dragonfly",
Long: `Scheduler is a long-running process which receives and manages download tasks from the dfdaemon, notify the seed peer to return to the source,
Long: `Scheduler is a long-running process which receives and manages download tasks from the dfdaemon, notify the seed peer to return to the source,
generate and maintain a P2P network during the download process, and push suitable download nodes to the dfdaemon`,
Args: cobra.NoArgs,
DisableAutoGenTag: true,
@ -72,7 +72,7 @@ generate and maintain a P2P network during the download process, and push suitab
MaxBackups: cfg.Server.LogMaxBackups}
// Initialize logger.
if err := logger.InitScheduler(cfg.Verbose, cfg.Console, d.LogDir(), rotateConfig); err != nil {
if err := logger.InitScheduler(cfg.Verbose, cfg.LogLevel, cfg.Console, d.LogDir(), rotateConfig); err != nil {
return fmt.Errorf("init scheduler logger: %w", err)
}
logger.RedirectStdoutAndStderr(cfg.Console, path.Join(d.LogDir(), types.SchedulerName))

View File

@ -165,6 +165,9 @@ console: false
# Whether to enable debug level logger and enable pprof.
verbose: true
# Use specific log level(debug, info, warn, error), take precedence over verbose flag.
# log-level: debug
# Listen port for pprof, only valid when the verbose option is true, default is -1.
pprof-port: -1

View File

@ -181,6 +181,9 @@ console: false
# Whether to enable debug level logger and enable pprof.
verbose: true
# Use specific log level(debug, info, warn, error), take precedence over verbose flag.
# log-level: debug
# Listen port for pprof, only valid when the verbose option is true, default is -1.
pprof-port: -1

View File

@ -17,6 +17,7 @@
package logger
import (
"fmt"
"strings"
"go.uber.org/atomic"
@ -52,7 +53,7 @@ var customCoreLevel atomic.Bool
var grpcLevel = zap.NewAtomicLevelAt(zapcore.WarnLevel)
var customGrpcLevel atomic.Bool
func CreateLogger(filePath string, compress bool, stats bool, verbose bool, config LogRotateConfig) (*zap.Logger, zap.AtomicLevel, error) {
func CreateLogger(filePath string, compress bool, stats bool, verbose bool, logLevel string, config LogRotateConfig) (*zap.Logger, zap.AtomicLevel, error) {
rotateConfig := &lumberjack.Logger{
Filename: filePath,
@ -66,10 +67,25 @@ func CreateLogger(filePath string, compress bool, stats bool, verbose bool, conf
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout(encodeTimeFormat)
var level = zap.NewAtomicLevel()
if verbose {
var level = zap.NewAtomicLevelAt(zap.InfoLevel)
// Use logLevel first, then fallback to verbose flag.
if logLevel != "" {
switch strings.ToLower(logLevel) {
case "debug":
level = zap.NewAtomicLevelAt(zapcore.DebugLevel)
case "info":
level = zap.NewAtomicLevelAt(zapcore.InfoLevel)
case "warn":
level = zap.NewAtomicLevelAt(zapcore.WarnLevel)
case "error":
level = zap.NewAtomicLevelAt(zapcore.ErrorLevel)
default:
fmt.Printf("Warning: invalid log level '%s', using 'info' instead\n", logLevel)
}
} else if verbose {
level = zap.NewAtomicLevelAt(zapcore.DebugLevel)
}
if strings.HasSuffix(filePath, GrpcLogFileName) && customGrpcLevel.Load() {
level = grpcLevel
} else if strings.HasSuffix(filePath, CoreLogFileName) && customCoreLevel.Load() {

View File

@ -17,10 +17,12 @@
package logger
import (
"fmt"
"io/fs"
"os"
"path"
"path/filepath"
"strings"
"go.uber.org/zap"
@ -33,9 +35,9 @@ type logInitMeta struct {
setLoggerFunc func(log *zap.Logger)
}
func InitManager(verbose, console bool, dir string, rotateConfig LogRotateConfig) error {
func InitManager(verbose bool, logLevel string, console bool, dir string, rotateConfig LogRotateConfig) error {
if console {
return createConsoleLogger(verbose)
return createConsoleLogger(verbose, logLevel)
}
logDir := filepath.Join(dir, types.ManagerName)
@ -62,12 +64,12 @@ func InitManager(verbose, console bool, dir string, rotateConfig LogRotateConfig
},
}
return createFileLogger(verbose, meta, logDir, rotateConfig)
return createFileLogger(verbose, logLevel, meta, logDir, rotateConfig)
}
func InitScheduler(verbose, console bool, dir string, rotateConfig LogRotateConfig) error {
func InitScheduler(verbose bool, logLevel string, console bool, dir string, rotateConfig LogRotateConfig) error {
if console {
return createConsoleLogger(verbose)
return createConsoleLogger(verbose, logLevel)
}
logDir := filepath.Join(dir, types.SchedulerName)
@ -90,12 +92,12 @@ func InitScheduler(verbose, console bool, dir string, rotateConfig LogRotateConf
},
}
return createFileLogger(verbose, meta, logDir, rotateConfig)
return createFileLogger(verbose, logLevel, meta, logDir, rotateConfig)
}
func InitDaemon(verbose, console bool, dir string, rotateConfig LogRotateConfig) error {
func InitDaemon(verbose bool, logLevel string, console bool, dir string, rotateConfig LogRotateConfig) error {
if console {
return createConsoleLogger(verbose)
return createConsoleLogger(verbose, logLevel)
}
logDir := filepath.Join(dir, types.DaemonName)
@ -118,12 +120,12 @@ func InitDaemon(verbose, console bool, dir string, rotateConfig LogRotateConfig)
},
}
return createFileLogger(verbose, meta, logDir, rotateConfig)
return createFileLogger(verbose, logLevel, meta, logDir, rotateConfig)
}
func InitDfget(verbose, console bool, dir string, rotateConfig LogRotateConfig) error {
func InitDfget(verbose bool, logLevel string, console bool, dir string, rotateConfig LogRotateConfig) error {
if console {
return createConsoleLogger(verbose)
return createConsoleLogger(verbose, logLevel)
}
logDir := filepath.Join(dir, types.DfgetName)
@ -138,10 +140,10 @@ func InitDfget(verbose, console bool, dir string, rotateConfig LogRotateConfig)
},
}
return createFileLogger(verbose, meta, logDir, rotateConfig)
return createFileLogger(verbose, logLevel, meta, logDir, rotateConfig)
}
func InitDfcache(console bool, dir string, rotateConfig LogRotateConfig) error {
func InitDfcache(verbose bool, logLevel string, dir string, rotateConfig LogRotateConfig) error {
logDir := filepath.Join(dir, types.DfcacheName)
var meta = []logInitMeta{
{
@ -154,16 +156,31 @@ func InitDfcache(console bool, dir string, rotateConfig LogRotateConfig) error {
},
}
return createFileLogger(console, meta, logDir, rotateConfig)
return createFileLogger(verbose, logLevel, meta, logDir, rotateConfig)
}
func createConsoleLogger(verbose bool) error {
func createConsoleLogger(verbose bool, logLevel string) error {
levels = nil
config := zap.NewDevelopmentConfig()
config.Level = zap.NewAtomicLevelAt(zap.InfoLevel)
if verbose {
// Use logLevel first, then fallback to verbose flag.
if logLevel != "" {
switch strings.ToLower(logLevel) {
case "debug":
config.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
case "info":
config.Level = zap.NewAtomicLevelAt(zap.InfoLevel)
case "warn":
config.Level = zap.NewAtomicLevelAt(zap.WarnLevel)
case "error":
config.Level = zap.NewAtomicLevelAt(zap.ErrorLevel)
default:
fmt.Printf("Warning: invalid log level '%s', using 'info' instead\n", logLevel)
}
} else if verbose {
config.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
}
log, err := config.Build(zap.AddCaller(), zap.AddStacktrace(zap.WarnLevel), zap.AddCallerSkip(1))
if err == nil {
sugar := log.Sugar()
@ -182,13 +199,13 @@ func createConsoleLogger(verbose bool) error {
return nil
}
func createFileLogger(verbose bool, meta []logInitMeta, logDir string, rotateConfig LogRotateConfig) error {
func createFileLogger(verbose bool, logLevel string, meta []logInitMeta, logDir string, rotateConfig LogRotateConfig) error {
levels = nil
// create parent dir first
_ = os.MkdirAll(logDir, fs.FileMode(0700))
for _, m := range meta {
log, level, err := CreateLogger(path.Join(logDir, m.fileName), false, false, verbose, rotateConfig)
log, level, err := CreateLogger(path.Join(logDir, m.fileName), false, false, verbose, logLevel, rotateConfig)
if err != nil {
return err
}

View File

@ -34,7 +34,7 @@ func SetGrpcLevel(level zapcore.Level) {
}
// SetupDaemon sets daemon log config: path, console
func SetupDaemon(logDir string, verbose bool, console bool, rotateConfig logger.LogRotateConfig) error {
func SetupDaemon(logDir string, verbose bool, logLevel string, console bool, rotateConfig logger.LogRotateConfig) error {
var options []dfpath.Option
if logDir != "" {
options = append(options, dfpath.WithLogDir(logDir))
@ -45,5 +45,5 @@ func SetupDaemon(logDir string, verbose bool, console bool, rotateConfig logger.
return err
}
return logger.InitDaemon(verbose, console, d.LogDir(), rotateConfig)
return logger.InitDaemon(verbose, logLevel, console, d.LogDir(), rotateConfig)
}

View File

@ -212,7 +212,7 @@ func (p *peerManager) RunGC(ctx context.Context) error {
if elapsed > p.hostTTL {
peer.Log.Info("peer elapsed exceeds the host ttl, causing the peer to leave")
if err := peer.FSM.Event(ctx, PeerEventLeave); err != nil {
peer.Log.Errorf("peer fsm event failed: %s", err.Error())
peer.Log.Infof("peer fsm event failed: %s", err.Error())
return true
}