From 3b2be8384c992e3fd69f16b97a6e5336a7c2115f Mon Sep 17 00:00:00 2001 From: Anna Shaleva Date: Fri, 21 Mar 2025 14:46:48 +0300 Subject: [PATCH] cli: add flag to enforce timestamps logging The solution described in #3358 is not acceptable for debugging. Signed-off-by: Anna Shaleva --- cli/options/options.go | 14 +++++++++++--- cli/server/dump_bin.go | 2 +- cli/server/server.go | 20 ++++++++++---------- cli/server/server_test.go | 17 +++++++++++------ cli/util/convert.go | 5 +++-- cli/util/upload_state.go | 2 +- cli/vm/cli.go | 2 +- 7 files changed, 38 insertions(+), 24 deletions(-) diff --git a/cli/options/options.go b/cli/options/options.go index b4e3d5267..6c23b336d 100644 --- a/cli/options/options.go +++ b/cli/options/options.go @@ -157,6 +157,14 @@ var Debug = &cli.BoolFlag{ Usage: "Enable debug logging (LOTS of output, overrides configuration)", } +// ForceTimestampLogs is a flag for commands that run the node. This flag +// enables timestamp logging for every log record even if program is running +// not in terminal. +var ForceTimestampLogs = &cli.BoolFlag{ + Name: "force-timestamp-logs", + Usage: "Enable timestamps for log entries", +} + var errInvalidHistoric = errors.New("invalid 'historic' parameter, neither a block number, nor a block/state hash") var errNoWallet = errors.New("no wallet parameter found, specify it with the '--wallet' or '-w' flag or specify wallet config file with the '--wallet-config' flag") var errConflictingWalletFlags = errors.New("--wallet flag conflicts with --wallet-config flag, please, provide one of them to specify wallet location") @@ -285,7 +293,7 @@ var ( // If logPath is configured on Windows -- function returns closer to be // able to close sink for the opened log output file. // If the program is run in TTY then logger adds timestamp to its entries. -func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap.Logger, *zap.AtomicLevel, func() error, error) { +func HandleLoggingParams(ctx *cli.Context, cfg config.ApplicationConfiguration) (*zap.Logger, *zap.AtomicLevel, func() error, error) { var ( level = zapcore.InfoLevel err error @@ -296,7 +304,7 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap. return nil, nil, nil, fmt.Errorf("log setting: %w", err) } } - if debug { + if ctx != nil && ctx.Bool("debug") { level = zapcore.DebugLevel } @@ -305,7 +313,7 @@ func HandleLoggingParams(debug bool, cfg config.ApplicationConfiguration) (*zap. cc.DisableStacktrace = true cc.EncoderConfig.EncodeDuration = zapcore.StringDurationEncoder cc.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder - if term.IsTerminal(int(os.Stdout.Fd())) { + if term.IsTerminal(int(os.Stdout.Fd())) || (ctx != nil && ctx.Bool("force-timestamp-logs")) { cc.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder } else { cc.EncoderConfig.EncodeTime = func(t time.Time, encoder zapcore.PrimitiveArrayEncoder) {} diff --git a/cli/server/dump_bin.go b/cli/server/dump_bin.go index dc3e9432a..08e98b51c 100644 --- a/cli/server/dump_bin.go +++ b/cli/server/dump_bin.go @@ -20,7 +20,7 @@ func dumpBin(ctx *cli.Context) error { if err != nil { return cli.Exit(err, 1) } - log, _, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) + log, _, logCloser, err := options.HandleLoggingParams(ctx, cfg.ApplicationConfiguration) if err != nil { return cli.Exit(err, 1) } diff --git a/cli/server/server.go b/cli/server/server.go index 82e8fdf6e..5b48aa94b 100644 --- a/cli/server/server.go +++ b/cli/server/server.go @@ -39,7 +39,7 @@ func NewCommands() []*cli.Command { cfgFlags = append(cfgFlags, options.Network...) var cfgWithCountFlags = slices.Clone(cfgFlags) - cfgFlags = append(cfgFlags, options.Debug) + cfgFlags = append(cfgFlags, options.Debug, options.ForceTimestampLogs) cfgWithCountFlags = append(cfgWithCountFlags, &cli.UintFlag{ Name: "count", @@ -87,7 +87,7 @@ func NewCommands() []*cli.Command { { Name: "node", Usage: "Start a NeoGo node", - UsageText: "neo-go node [--config-path path] [-d] [-p/-m/-t] [--config-file file]", + UsageText: "neo-go node [--config-path path] [-d] [-p/-m/-t] [--config-file file] [--force-timestamp-logs]", Action: startServer, Flags: cfgFlags, }, @@ -98,28 +98,28 @@ func NewCommands() []*cli.Command { { Name: "dump", Usage: "Dump blocks (starting with the genesis or specified block) to the file", - UsageText: "neo-go db dump [-o file] [-s start] [-c count] [--config-path path] [-p/-m/-t] [--config-file file]", + UsageText: "neo-go db dump [-o file] [-s start] [-c count] [--config-path path] [-p/-m/-t] [--config-file file] [--force-timestamp-logs]", Action: dumpDB, Flags: cfgCountOutFlags, }, { Name: "dump-bin", Usage: "Dump blocks (starting with the genesis or specified block) to the directory in binary format", - UsageText: "neo-go db dump-bin -o directory [-s start] [-c count] [--config-path path] [-p/-m/-t] [--config-file file]", + UsageText: "neo-go db dump-bin -o directory [-s start] [-c count] [--config-path path] [-p/-m/-t] [--config-file file] [--force-timestamp-logs]", Action: dumpBin, Flags: cfgCountOutFlags, }, { Name: "restore", Usage: "Restore blocks from the file", - UsageText: "neo-go db restore [-i file] [--dump] [-n] [-c count] [--config-path path] [-p/-m/-t] [--config-file file]", + UsageText: "neo-go db restore [-i file] [--dump] [-n] [-c count] [--config-path path] [-p/-m/-t] [--config-file file] [--force-timestamp-logs]", Action: restoreDB, Flags: cfgCountInFlags, }, { Name: "reset", Usage: "Reset database to the previous state", - UsageText: "neo-go db reset --height height [--config-path path] [-p/-m/-t] [--config-file file]", + UsageText: "neo-go db reset --height height [--config-path path] [-p/-m/-t] [--config-file file] [--force-timestamp-logs]", Action: resetDB, Flags: cfgHeightFlags, }, @@ -170,7 +170,7 @@ func dumpDB(ctx *cli.Context) error { if err != nil { return cli.Exit(err, 1) } - log, _, logCloser, err := options.HandleLoggingParams(ctx.Bool("debug"), cfg.ApplicationConfiguration) + log, _, logCloser, err := options.HandleLoggingParams(ctx, cfg.ApplicationConfiguration) if err != nil { return cli.Exit(err, 1) } @@ -226,7 +226,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, cfg.ApplicationConfiguration) if err != nil { return cli.Exit(err, 1) } @@ -345,7 +345,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, cfg.ApplicationConfiguration) if err != nil { return cli.Exit(err, 1) } @@ -455,7 +455,7 @@ func startServer(ctx *cli.Context) error { return cli.Exit(err, 1) } var logDebug = ctx.Bool("debug") - log, logLevel, logCloser, err := options.HandleLoggingParams(logDebug, cfg.ApplicationConfiguration) + log, logLevel, logCloser, err := options.HandleLoggingParams(ctx, cfg.ApplicationConfiguration) if err != nil { return cli.Exit(err, 1) } diff --git a/cli/server/server_test.go b/cli/server/server_test.go index b988d46f7..50aed3e74 100644 --- a/cli/server/server_test.go +++ b/cli/server/server_test.go @@ -88,6 +88,9 @@ func TestGetConfigFromContext(t *testing.T) { func TestHandleLoggingParams(t *testing.T) { d := t.TempDir() testLog := filepath.Join(d, "file.log") + set := flag.NewFlagSet("flagSet", flag.ExitOnError) + debug := set.Bool("debug", false, "") + ctx := cli.NewContext(cli.NewApp(), set, nil) t.Run("logdir is a file", func(t *testing.T) { logfile := filepath.Join(d, "logdir") @@ -95,7 +98,7 @@ func TestHandleLoggingParams(t *testing.T) { cfg := config.ApplicationConfiguration{ LogPath: filepath.Join(logfile, "file.log"), } - _, lvl, closer, err := options.HandleLoggingParams(false, cfg) + _, lvl, closer, err := options.HandleLoggingParams(ctx, cfg) require.Error(t, err) require.Nil(t, lvl) require.Nil(t, closer) @@ -106,7 +109,7 @@ func TestHandleLoggingParams(t *testing.T) { LogPath: testLog, LogLevel: "qwerty", } - _, lvl, closer, err := options.HandleLoggingParams(false, cfg) + _, lvl, closer, err := options.HandleLoggingParams(ctx, cfg) require.Error(t, err) require.Nil(t, lvl) require.Nil(t, closer) @@ -116,7 +119,7 @@ func TestHandleLoggingParams(t *testing.T) { cfg := config.ApplicationConfiguration{ LogPath: testLog, } - logger, lvl, closer, err := options.HandleLoggingParams(false, cfg) + logger, lvl, closer, err := options.HandleLoggingParams(ctx, cfg) require.NotNil(t, lvl) require.NoError(t, err) t.Cleanup(func() { @@ -134,7 +137,7 @@ func TestHandleLoggingParams(t *testing.T) { LogPath: testLog, LogLevel: "warn", } - logger, lvl, closer, err := options.HandleLoggingParams(false, cfg) + logger, lvl, closer, err := options.HandleLoggingParams(ctx, cfg) require.NoError(t, err) t.Cleanup(func() { if closer != nil { @@ -150,7 +153,9 @@ func TestHandleLoggingParams(t *testing.T) { cfg := config.ApplicationConfiguration{ LogPath: testLog, } - logger, lvl, closer, err := options.HandleLoggingParams(true, cfg) + *debug = true + t.Cleanup(func() { *debug = false }) + logger, lvl, closer, err := options.HandleLoggingParams(ctx, cfg) require.NoError(t, err) t.Cleanup(func() { if closer != nil { @@ -176,7 +181,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(ctx, cfg.ApplicationConfiguration) require.NoError(t, err) t.Cleanup(func() { if closer != nil { diff --git a/cli/util/convert.go b/cli/util/convert.go index 487ba5df4..121509e38 100644 --- a/cli/util/convert.go +++ b/cli/util/convert.go @@ -87,6 +87,7 @@ func NewCommands() []*cli.Command { Value: 20, }, options.Debug, + options.ForceTimestampLogs, }, options.RPC...) uploadBinFlags = append(uploadBinFlags, options.Wallet...) uploadBinFlags = append(uploadBinFlags, neoFSFlags...) @@ -98,7 +99,7 @@ func NewCommands() []*cli.Command { Value: neofs.DefaultStateAttribute, Action: cmdargs.EnsureNotEmpty("state-attribute"), }, - options.Debug, options.Config, options.ConfigFile, options.RelativePath, + options.Debug, options.ForceTimestampLogs, options.Config, options.ConfigFile, options.RelativePath, }, options.Wallet...) uploadStateFlags = append(uploadStateFlags, options.Network...) uploadStateFlags = append(uploadStateFlags, neoFSFlags...) @@ -189,7 +190,7 @@ func NewCommands() []*cli.Command { { Name: "upload-state", Usage: "Start the node, traverse MPT and upload MPT nodes to the NeoFS container at every StateSyncInterval number of blocks", - UsageText: "neo-go util upload-state --fs-rpc-endpoint [,[...]] --container --state-attribute state --wallet [--wallet-config ] [--address
] [--searchers ] [--retries ] [--debug] [--config-path path] [-p/-m/-t] [--config-file file]", + UsageText: "neo-go util upload-state --fs-rpc-endpoint [,[...]] --container --state-attribute state --wallet [--wallet-config ] [--address
] [--searchers ] [--retries ] [--debug] [--config-path path] [-p/-m/-t] [--config-file file] [--force-timestamp-logs]", Action: uploadState, Flags: uploadStateFlags, }, diff --git a/cli/util/upload_state.go b/cli/util/upload_state.go index 8d14c9629..0e47d7475 100644 --- a/cli/util/upload_state.go +++ b/cli/util/upload_state.go @@ -45,7 +45,7 @@ func uploadState(ctx *cli.Context) error { return cli.Exit(err, 1) } defer p.Close() - log, _, logCloser, err := options.HandleLoggingParams(debug, cfg.ApplicationConfiguration) + log, _, logCloser, err := options.HandleLoggingParams(ctx, cfg.ApplicationConfiguration) if err != nil { return cli.Exit(err, 1) } diff --git a/cli/vm/cli.go b/cli/vm/cli.go index cb111999b..66ffe9950 100644 --- a/cli/vm/cli.go +++ b/cli/vm/cli.go @@ -480,7 +480,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(nil, cfg.ApplicationConfiguration) if err != nil { return nil, cli.Exit(fmt.Errorf("failed to init logger: %w", err), 1) }