From 06225e332eaeb63eceb3aacb11dccf48b0cbf42f Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Fri, 16 Nov 2018 03:05:06 +0400 Subject: [PATCH] Config option for JSON output formatter (#2843) * Introduce a structured logging option * rename StructuredLog to LogFormat * add changelog entry * move log_format under log_level --- CHANGELOG_PENDING.md | 2 ++ cmd/tendermint/commands/root.go | 3 +++ config/config.go | 23 +++++++++++++++++++++++ config/toml.go | 3 +++ docs/tendermint-core/configuration.md | 3 +++ 5 files changed, 34 insertions(+) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index eea80c57..63b27711 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -26,6 +26,8 @@ program](https://hackerone.com/tendermint). ### FEATURES: +- [log] new `log_format` config option, which can be set to 'plain' for colored + text or 'json' for JSON output ### IMPROVEMENTS: diff --git a/cmd/tendermint/commands/root.go b/cmd/tendermint/commands/root.go index 89ffbe74..6d79f75c 100644 --- a/cmd/tendermint/commands/root.go +++ b/cmd/tendermint/commands/root.go @@ -54,6 +54,9 @@ var RootCmd = &cobra.Command{ if err != nil { return err } + if config.LogFormat == cfg.LogFormatJSON { + logger = log.NewTMJSONLogger(log.NewSyncWriter(os.Stdout)) + } logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel()) if err != nil { return err diff --git a/config/config.go b/config/config.go index ea6582c0..23b03399 100644 --- a/config/config.go +++ b/config/config.go @@ -14,6 +14,11 @@ const ( FuzzModeDrop = iota // FuzzModeDelay is a mode in which we randomly sleep FuzzModeDelay + + // LogFormatPlain is a format for colored text + LogFormatPlain = "plain" + // LogFormatJSON is a format for json output + LogFormatJSON = "json" ) // NOTE: Most of the structs & relevant comments + the @@ -94,6 +99,9 @@ func (cfg *Config) SetRoot(root string) *Config { // ValidateBasic performs basic validation (checking param bounds, etc.) and // returns an error if any check fails. func (cfg *Config) ValidateBasic() error { + if err := cfg.BaseConfig.ValidateBasic(); err != nil { + return err + } if err := cfg.RPC.ValidateBasic(); err != nil { return errors.Wrap(err, "Error in [rpc] section") } @@ -145,6 +153,9 @@ type BaseConfig struct { // Output level for logging LogLevel string `mapstructure:"log_level"` + // Output format: 'plain' (colored text) or 'json' + LogFormat string `mapstructure:"log_format"` + // Path to the JSON file containing the initial validator set and other meta data Genesis string `mapstructure:"genesis_file"` @@ -179,6 +190,7 @@ func DefaultBaseConfig() BaseConfig { ProxyApp: "tcp://127.0.0.1:26658", ABCI: "socket", LogLevel: DefaultPackageLogLevels(), + LogFormat: LogFormatPlain, ProfListenAddress: "", FastSync: true, FilterPeers: false, @@ -221,6 +233,17 @@ func (cfg BaseConfig) DBDir() string { return rootify(cfg.DBPath, cfg.RootDir) } +// ValidateBasic performs basic validation (checking param bounds, etc.) and +// returns an error if any check fails. +func (cfg BaseConfig) ValidateBasic() error { + switch cfg.LogFormat { + case LogFormatPlain, LogFormatJSON: + default: + return errors.New("unknown log_format (must be 'plain' or 'json')") + } + return nil +} + // DefaultLogLevel returns a default log level of "error" func DefaultLogLevel() string { return "error" diff --git a/config/toml.go b/config/toml.go index 89be3783..6f0578e4 100644 --- a/config/toml.go +++ b/config/toml.go @@ -86,6 +86,9 @@ db_dir = "{{ js .BaseConfig.DBPath }}" # Output level for logging, including package level options log_level = "{{ .BaseConfig.LogLevel }}" +# Output format: 'plain' (colored text) or 'json' +log_format = "{{ .BaseConfig.LogFormat }}" + ##### additional base config options ##### # Path to the JSON file containing the initial validator set and other meta data diff --git a/docs/tendermint-core/configuration.md b/docs/tendermint-core/configuration.md index 7052ca50..13894a30 100644 --- a/docs/tendermint-core/configuration.md +++ b/docs/tendermint-core/configuration.md @@ -39,6 +39,9 @@ db_dir = "data" # Output level for logging log_level = "state:info,*:error" +# Output format: 'plain' (colored text) or 'json' +log_format = "plain" + ##### additional base config options ##### # The ID of the chain to join (should be signed with every transaction and vote)