cli: make the node use new logging level on SIGHUP

Fixes #2794.
This commit is contained in:
Roman Khimov 2022-12-05 15:43:55 +03:00
parent cceb044a02
commit 2e1b502463
5 changed files with 40 additions and 16 deletions

View file

@ -171,7 +171,7 @@ var (
// If logPath is configured -- function creates a dir and a file for logging. // If logPath is configured -- function creates a dir and a file for logging.
// If logPath is configured on Windows -- function returns closer to be // If logPath is configured on Windows -- function returns closer to be
// able to close sink for the opened log output file. // 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 ( var (
level = zapcore.InfoLevel level = zapcore.InfoLevel
err error err error
@ -179,7 +179,7 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.
if len(cfg.LogLevel) > 0 { if len(cfg.LogLevel) > 0 {
level, err = zapcore.ParseLevel(cfg.LogLevel) level, err = zapcore.ParseLevel(cfg.LogLevel)
if err != nil { if err != nil {
return nil, nil, fmt.Errorf("log setting: %w", err) return nil, nil, nil, fmt.Errorf("log setting: %w", err)
} }
} }
if debug { if debug {
@ -198,7 +198,7 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.
if logPath := cfg.LogPath; logPath != "" { if logPath := cfg.LogPath; logPath != "" {
if err := io.MakeDirForFile(logPath, "logger"); err != nil { if err := io.MakeDirForFile(logPath, "logger"); err != nil {
return nil, nil, err return nil, nil, nil, err
} }
if runtime.GOOS == "windows" { if runtime.GOOS == "windows" {
@ -236,7 +236,7 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.
return f, err return f, err
}) })
if err != nil { 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 _winfileSinkRegistered = true
} }
@ -247,5 +247,5 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.
} }
log, err := cc.Build() log, err := cc.Build()
return log, _winfileSinkCloser, err return log, &cc.Level, _winfileSinkCloser, err
} }

View file

@ -29,6 +29,7 @@ import (
"github.com/nspcc-dev/neo-go/pkg/services/stateroot" "github.com/nspcc-dev/neo-go/pkg/services/stateroot"
"github.com/urfave/cli" "github.com/urfave/cli"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore"
) )
// NewCommands returns 'node' command. // NewCommands returns 'node' command.
@ -154,7 +155,7 @@ func dumpDB(ctx *cli.Context) error {
if err != nil { if err != nil {
return cli.NewExitError(err, 1) 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 { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
@ -207,7 +208,7 @@ func restoreDB(ctx *cli.Context) error {
if err != nil { if err != nil {
return err 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 { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
@ -326,7 +327,7 @@ func resetDB(ctx *cli.Context) error {
} }
h := uint32(ctx.Uint("height")) 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 { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
@ -427,7 +428,8 @@ func startServer(ctx *cli.Context) error {
if err != nil { if err != nil {
return cli.NewExitError(err, 1) 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 { if err != nil {
return cli.NewExitError(err, 1) return cli.NewExitError(err, 1)
} }
@ -499,6 +501,8 @@ Main:
shutdownErr = fmt.Errorf("server error: %w", err) shutdownErr = fmt.Errorf("server error: %w", err)
cancel() cancel()
case sig := <-sigCh: case sig := <-sigCh:
var newLogLevel = zapcore.InvalidLevel
log.Info("signal received", zap.Stringer("name", sig)) log.Info("signal received", zap.Stringer("name", sig))
cfgnew, err := options.GetConfigFromContext(ctx) cfgnew, err := options.GetConfigFromContext(ctx)
if err != nil { if err != nil {
@ -513,9 +517,20 @@ Main:
log.Warn("ApplicationConfiguration changed in incompatible way, signal ignored") log.Warn("ApplicationConfiguration changed in incompatible way, signal ignored")
break // Continue working. 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) configureAddresses(&cfgnew.ApplicationConfiguration)
switch sig { switch sig {
case sighup: case sighup:
if newLogLevel != zapcore.InvalidLevel {
logLevel.SetLevel(newLogLevel)
log.Warn("using new logging level", zap.Stringer("level", newLogLevel))
}
serv.DelService(&rpcServer) serv.DelService(&rpcServer)
rpcServer.Shutdown() rpcServer.Shutdown()
rpcServer = rpcsrv.New(chain, cfgnew.ApplicationConfiguration.RPC, serv, oracleSrv, log, errChan) rpcServer = rpcsrv.New(chain, cfgnew.ApplicationConfiguration.RPC, serv, oracleSrv, log, errChan)

View file

@ -49,8 +49,9 @@ func TestHandleLoggingParams(t *testing.T) {
cfg := config.ApplicationConfiguration{ cfg := config.ApplicationConfiguration{
LogPath: filepath.Join(logfile, "file.log"), LogPath: filepath.Join(logfile, "file.log"),
} }
_, closer, err := options.HandleLoggingParams(false, cfg) _, lvl, closer, err := options.HandleLoggingParams(false, cfg)
require.Error(t, err) require.Error(t, err)
require.Nil(t, lvl)
require.Nil(t, closer) require.Nil(t, closer)
}) })
@ -59,8 +60,9 @@ func TestHandleLoggingParams(t *testing.T) {
LogPath: testLog, LogPath: testLog,
LogLevel: "qwerty", LogLevel: "qwerty",
} }
_, closer, err := options.HandleLoggingParams(false, cfg) _, lvl, closer, err := options.HandleLoggingParams(false, cfg)
require.Error(t, err) require.Error(t, err)
require.Nil(t, lvl)
require.Nil(t, closer) require.Nil(t, closer)
}) })
@ -68,13 +70,15 @@ func TestHandleLoggingParams(t *testing.T) {
cfg := config.ApplicationConfiguration{ cfg := config.ApplicationConfiguration{
LogPath: testLog, 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) require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
if closer != nil { if closer != nil {
require.NoError(t, closer()) require.NoError(t, closer())
} }
}) })
require.Equal(t, zapcore.InfoLevel, lvl.Level())
require.True(t, logger.Core().Enabled(zapcore.InfoLevel)) require.True(t, logger.Core().Enabled(zapcore.InfoLevel))
require.False(t, logger.Core().Enabled(zapcore.DebugLevel)) require.False(t, logger.Core().Enabled(zapcore.DebugLevel))
}) })
@ -84,13 +88,14 @@ func TestHandleLoggingParams(t *testing.T) {
LogPath: testLog, LogPath: testLog,
LogLevel: "warn", LogLevel: "warn",
} }
logger, closer, err := options.HandleLoggingParams(false, cfg) logger, lvl, closer, err := options.HandleLoggingParams(false, cfg)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
if closer != nil { if closer != nil {
require.NoError(t, closer()) require.NoError(t, closer())
} }
}) })
require.Equal(t, zapcore.WarnLevel, lvl.Level())
require.True(t, logger.Core().Enabled(zapcore.WarnLevel)) require.True(t, logger.Core().Enabled(zapcore.WarnLevel))
require.False(t, logger.Core().Enabled(zapcore.InfoLevel)) require.False(t, logger.Core().Enabled(zapcore.InfoLevel))
}) })
@ -99,13 +104,14 @@ func TestHandleLoggingParams(t *testing.T) {
cfg := config.ApplicationConfiguration{ cfg := config.ApplicationConfiguration{
LogPath: testLog, LogPath: testLog,
} }
logger, closer, err := options.HandleLoggingParams(true, cfg) logger, lvl, closer, err := options.HandleLoggingParams(true, cfg)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
if closer != nil { if closer != nil {
require.NoError(t, closer()) 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.InfoLevel))
require.True(t, logger.Core().Enabled(zapcore.DebugLevel)) require.True(t, logger.Core().Enabled(zapcore.DebugLevel))
}) })
@ -124,7 +130,7 @@ func TestInitBCWithMetrics(t *testing.T) {
ctx := cli.NewContext(cli.NewApp(), set, nil) ctx := cli.NewContext(cli.NewApp(), set, nil)
cfg, err := options.GetConfigFromContext(ctx) cfg, err := options.GetConfigFromContext(ctx)
require.NoError(t, err) require.NoError(t, err)
logger, closer, err := options.HandleLoggingParams(true, cfg.ApplicationConfiguration) logger, _, closer, err := options.HandleLoggingParams(true, cfg.ApplicationConfiguration)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { t.Cleanup(func() {
if closer != nil { if closer != nil {

View file

@ -448,7 +448,7 @@ func NewWithConfig(printLogotype bool, onExit func(int), c *readline.Config, cfg
store = storage.NewMemoryStore() store = storage.NewMemoryStore()
} }
log, logCloser, err := options.HandleLoggingParams(false, cfg.ApplicationConfiguration) log, _, logCloser, err := options.HandleLoggingParams(false, cfg.ApplicationConfiguration)
if err != nil { if err != nil {
return nil, cli.NewExitError(fmt.Errorf("failed to init logger: %w", err), 1) return nil, cli.NewExitError(fmt.Errorf("failed to init logger: %w", err), 1)
} }

View file

@ -83,6 +83,9 @@ are broadly split into three main categories:
* consensus * consensus
That's dBFT, it's a special one and it's controlled with USR2. 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): Typical scenarios when this can be useful (without full node restart):
* enabling some service * enabling some service
* changing RPC configuration * changing RPC configuration