diff --git a/cli/options/options.go b/cli/options/options.go index 0423e51cb..e5e5f45b3 100644 --- a/cli/options/options.go +++ b/cli/options/options.go @@ -171,7 +171,7 @@ var ( // If logPath is configured -- function creates a dir and a file for logging. // If logPath is configured on Windows -- function returns closer to be // able to close sink for the opened log output file. -func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.Logger, func() error, error) { +func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.Logger, *zap.AtomicLevel, func() error, error) { var ( level = zapcore.InfoLevel err error @@ -179,7 +179,7 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap. if len(cfg.LogLevel) > 0 { level, err = zapcore.ParseLevel(cfg.LogLevel) if err != nil { - return nil, nil, fmt.Errorf("log setting: %w", err) + return nil, nil, nil, fmt.Errorf("log setting: %w", err) } } if debug { @@ -198,7 +198,7 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap. if logPath := cfg.LogPath; logPath != "" { if err := io.MakeDirForFile(logPath, "logger"); err != nil { - return nil, nil, err + return nil, nil, nil, err } if runtime.GOOS == "windows" { @@ -236,7 +236,7 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap. return f, err }) if err != nil { - return nil, nil, fmt.Errorf("failed to register windows-specific sinc: %w", err) + return nil, nil, nil, fmt.Errorf("failed to register windows-specific sinc: %w", err) } _winfileSinkRegistered = true } @@ -247,5 +247,5 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap. } log, err := cc.Build() - return log, _winfileSinkCloser, err + return log, &cc.Level, _winfileSinkCloser, err } diff --git a/cli/server/server.go b/cli/server/server.go index 9d47ab47a..b48a7ac15 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -29,6 +29,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/services/stateroot" "github.com/urfave/cli" "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) // NewCommands returns 'node' command. @@ -154,7 +155,7 @@ func dumpDB(ctx *cli.Context) error { if err != nil { return cli.NewExitError(err, 1) } - log, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) + log, _, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) if err != nil { return cli.NewExitError(err, 1) } @@ -207,7 +208,7 @@ func restoreDB(ctx *cli.Context) error { if err != nil { return err } - log, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) + log, _, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) if err != nil { return cli.NewExitError(err, 1) } @@ -326,7 +327,7 @@ func resetDB(ctx *cli.Context) error { } h := uint32(ctx.Uint("height")) - log, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) + log, _, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) if err != nil { return cli.NewExitError(err, 1) } @@ -427,7 +428,8 @@ func startServer(ctx *cli.Context) error { if err != nil { return cli.NewExitError(err, 1) } - log, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) + var logDebug = ctx.Bool("debug") + log, logLevel, logCloser, err := options.HandleLoggingParams(logDebug, cfg.ApplicationConfiguration) if err != nil { return cli.NewExitError(err, 1) } @@ -499,6 +501,8 @@ Main: shutdownErr = fmt.Errorf("server error: %w", err) cancel() case sig := <-sigCh: + var newLogLevel = zapcore.InvalidLevel + log.Info("signal received", zap.Stringer("name", sig)) cfgnew, err := options.GetConfigFromContext(ctx) if err != nil { @@ -513,9 +517,20 @@ Main: log.Warn("ApplicationConfiguration changed in incompatible way, signal ignored") break // Continue working. } + if !logDebug && cfgnew.ApplicationConfiguration.LogLevel != cfg.ApplicationConfiguration.LogLevel { + newLogLevel, err = zapcore.ParseLevel(cfgnew.ApplicationConfiguration.LogLevel) + if err != nil { + log.Warn("wrong LogLevel in ApplicationConfiguration, signal ignored", zap.Error(err)) + break // Continue working. + } + } configureAddresses(&cfgnew.ApplicationConfiguration) switch sig { case sighup: + if newLogLevel != zapcore.InvalidLevel { + logLevel.SetLevel(newLogLevel) + log.Warn("using new logging level", zap.Stringer("level", newLogLevel)) + } serv.DelService(&rpcServer) rpcServer.Shutdown() rpcServer = rpcsrv.New(chain, cfgnew.ApplicationConfiguration.RPC, serv, oracleSrv, log, errChan) diff --git a/cli/server/server_test.go b/cli/server/server_test.go index a750342ae..f13d4664b 100644 --- a/cli/server/server_test.go +++ b/cli/server/server_test.go @@ -49,8 +49,9 @@ func TestHandleLoggingParams(t *testing.T) { cfg := config.ApplicationConfiguration{ LogPath: filepath.Join(logfile, "file.log"), } - _, closer, err := options.HandleLoggingParams(false, cfg) + _, lvl, closer, err := options.HandleLoggingParams(false, cfg) require.Error(t, err) + require.Nil(t, lvl) require.Nil(t, closer) }) @@ -59,8 +60,9 @@ func TestHandleLoggingParams(t *testing.T) { LogPath: testLog, LogLevel: "qwerty", } - _, closer, err := options.HandleLoggingParams(false, cfg) + _, lvl, closer, err := options.HandleLoggingParams(false, cfg) require.Error(t, err) + require.Nil(t, lvl) require.Nil(t, closer) }) @@ -68,13 +70,15 @@ func TestHandleLoggingParams(t *testing.T) { cfg := config.ApplicationConfiguration{ LogPath: testLog, } - logger, closer, err := options.HandleLoggingParams(false, cfg) + logger, lvl, closer, err := options.HandleLoggingParams(false, cfg) + require.NotNil(t, lvl) require.NoError(t, err) t.Cleanup(func() { if closer != nil { require.NoError(t, closer()) } }) + require.Equal(t, zapcore.InfoLevel, lvl.Level()) require.True(t, logger.Core().Enabled(zapcore.InfoLevel)) require.False(t, logger.Core().Enabled(zapcore.DebugLevel)) }) @@ -84,13 +88,14 @@ func TestHandleLoggingParams(t *testing.T) { LogPath: testLog, LogLevel: "warn", } - logger, closer, err := options.HandleLoggingParams(false, cfg) + logger, lvl, closer, err := options.HandleLoggingParams(false, cfg) require.NoError(t, err) t.Cleanup(func() { if closer != nil { require.NoError(t, closer()) } }) + require.Equal(t, zapcore.WarnLevel, lvl.Level()) require.True(t, logger.Core().Enabled(zapcore.WarnLevel)) require.False(t, logger.Core().Enabled(zapcore.InfoLevel)) }) @@ -99,13 +104,14 @@ func TestHandleLoggingParams(t *testing.T) { cfg := config.ApplicationConfiguration{ LogPath: testLog, } - logger, closer, err := options.HandleLoggingParams(true, cfg) + logger, lvl, closer, err := options.HandleLoggingParams(true, cfg) require.NoError(t, err) t.Cleanup(func() { if closer != nil { require.NoError(t, closer()) } }) + require.Equal(t, zapcore.DebugLevel, lvl.Level()) require.True(t, logger.Core().Enabled(zapcore.InfoLevel)) require.True(t, logger.Core().Enabled(zapcore.DebugLevel)) }) @@ -124,7 +130,7 @@ func TestInitBCWithMetrics(t *testing.T) { ctx := cli.NewContext(cli.NewApp(), set, nil) cfg, err := options.GetConfigFromContext(ctx) require.NoError(t, err) - logger, closer, err := options.HandleLoggingParams(true, cfg.ApplicationConfiguration) + logger, _, closer, err := options.HandleLoggingParams(true, cfg.ApplicationConfiguration) require.NoError(t, err) t.Cleanup(func() { if closer != nil { diff --git a/cli/vm/cli.go b/cli/vm/cli.go index 9ee107cf2..e2c988bd5 100644 --- a/cli/vm/cli.go +++ b/cli/vm/cli.go @@ -448,7 +448,7 @@ func NewWithConfig(printLogotype bool, onExit func(int), c *readline.Config, cfg store = storage.NewMemoryStore() } - log, logCloser, err := options.HandleLoggingParams(false, cfg.ApplicationConfiguration) + log, _, logCloser, err := options.HandleLoggingParams(false, cfg.ApplicationConfiguration) if err != nil { return nil, cli.NewExitError(fmt.Errorf("failed to init logger: %w", err), 1) } diff --git a/docs/cli.md b/docs/cli.md index 2f480771e..ed8ff0984 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -83,6 +83,9 @@ are broadly split into three main categories: * consensus That's dBFT, it's a special one and it's controlled with USR2. +HUP signal also reconfigures logging level if it's changed in the +configuration file (LogLevel option in ApplicationConfig). + Typical scenarios when this can be useful (without full node restart): * enabling some service * changing RPC configuration