Files
prysm/cmd/validator/usage.go
Tushar Jain ca8cc65d72 Add --disable-log-color flag (#16574)
<!-- Thanks for sending a PR! Before submitting:

1. If this is your first PR, check out our contribution guide here
https://docs.prylabs.network/docs/contribute/contribution-guidelines
You will then need to sign our Contributor License Agreement (CLA),
which will show up as a comment from a bot in this pull request after
you open it. We cannot review code without a signed CLA.
2. Please file an associated tracking issue if this pull request is
non-trivial and requires context for our team to understand. All
features and most bug fixes should have
an associated issue with a design discussed and decided upon. Small bug
   fixes and documentation improvements don't need issues.
3. New features and bug fixes must have tests. Documentation may need to
be updated. If you're unsure what to update, send the PR, and we'll
discuss
   in review.
4. Note that PRs updating dependencies and new Go versions are not
accepted.
   Please file an issue instead.
5. A changelog entry is required for user facing issues.
-->

**What type of PR is this?**

Feature

**What does this PR do? Why is it needed?**

This PR adds a --disable-log-color boolean flag to both the beacon-chain
and validator binaries. When set, DisableColors=true is passed to the
text formatter, suppressing ANSI codes regardless of whether the output
is a TTY. Default behavior (colors on) is unchanged.
Since 7.1.3, Prysm forces ANSI color codes in text log output
unconditionally via formatter.ForceColors = true in the
prefixed.TextFormatter setup. This causes raw escape sequences (e.g.
^[[32m) to appear when stderr is redirected to a file, pipe, or log
aggregator.

**Which issues(s) does this PR fix?**
Fixes #16570 

**Other notes for review**
**Tested by doing the following**
1. Build both binaries:
     bazel build //cmd/beacon-chain:beacon-chain
bazel build //cmd/validator:validator
   
2. Verify flag appears in help: 
```
 ./bazel-bin/cmd/beacon-chain/beacon-chain_/beacon-chain --help | grep disable-log-color
./bazel-bin/cmd/validator/validator_/validator --help | grep disable-log-color
```
   
3. Confirm colors are present by default when redirected (existing
behavior):
```
 ./bazel-bin/cmd/beacon-chain/beacon-chain_/beacon-chain
./bazel-bin/cmd/validator/validator_/validator
```                               
4. Confirm colors are suppressed with the flag:
```
./bazel-bin/cmd/beacon-chain/beacon-chain_/beacon-chain --disable-log-color
./bazel-bin/cmd/validator/validator_/validator --disable-log-color
```

**Acknowledgements**

- [x] I have read
[CONTRIBUTING.md](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md).
- [x] I have included a uniquely named [changelog fragment
file](https://github.com/prysmaticlabs/prysm/blob/develop/CONTRIBUTING.md#maintaining-changelogmd).
- [x] I have added a description with sufficient context for reviewers
to understand this PR.
- [x] I have tested that my changes work as expected and I added a
testing plan to the PR description (if applicable).

---------

Co-authored-by: Bastin <43618253+Inspector-Butters@users.noreply.github.com>
2026-03-25 14:36:29 +00:00

188 lines
3.9 KiB
Go

// This code was adapted from https://github.com/ethereum/go-ethereum/blob/master/cmd/geth/usage.go
package main
import (
"io"
"sort"
"github.com/OffchainLabs/prysm/v7/cmd"
"github.com/OffchainLabs/prysm/v7/cmd/validator/flags"
"github.com/OffchainLabs/prysm/v7/config/features"
"github.com/OffchainLabs/prysm/v7/runtime/debug"
"github.com/urfave/cli/v2"
)
var appHelpTemplate = `NAME:
{{.App.Name}} - {{.App.Usage}}
USAGE:
{{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}}
{{if .App.Version}}
VERSION:
{{.App.Version}}
{{end -}}
{{if len .App.Authors}}
AUTHORS:
{{range .App.Authors}}{{ . }}
{{end -}}
{{end -}}
{{if .App.Commands}}
global OPTIONS:
{{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
{{end -}}
{{end -}}
{{if .FlagGroups}}
{{range .FlagGroups}}{{.Name}} OPTIONS:
{{range .Flags}}{{.}}
{{end}}
{{end -}}
{{end -}}
{{if .App.Copyright }}
COPYRIGHT:
{{.App.Copyright}}
{{end -}}
`
type flagGroup struct {
Name string
Flags []cli.Flag
}
var appHelpFlagGroups = []flagGroup{
{
Name: "cmd",
Flags: []cli.Flag{
cmd.MinimalConfigFlag,
cmd.E2EConfigFlag,
cmd.VerbosityFlag,
cmd.DataDirFlag,
flags.WalletDirFlag,
flags.WalletPasswordFileFlag,
cmd.ClearDB,
cmd.ForceClearDB,
cmd.EnableBackupWebhookFlag,
cmd.EnableTracingFlag,
cmd.TracingProcessNameFlag,
cmd.TracingEndpointFlag,
cmd.TraceSampleFractionFlag,
cmd.MonitoringHostFlag,
flags.MonitoringPortFlag,
cmd.DisableMonitoringFlag,
cmd.DisableLogColor,
cmd.LogFormat,
cmd.LogFileName,
cmd.ConfigFileFlag,
cmd.ChainConfigFileFlag,
cmd.GrpcMaxCallRecvMsgSizeFlag,
cmd.AcceptTosFlag,
cmd.ApiTimeoutFlag,
flags.DisableEphemeralLogFile,
cmd.LogVModuleFlag,
},
},
{
Name: "debug",
Flags: []cli.Flag{
debug.PProfFlag,
debug.PProfAddrFlag,
debug.PProfPortFlag,
debug.MemProfileRateFlag,
debug.BlockProfileRateFlag,
debug.MutexProfileFractionFlag,
},
},
{
Name: "rpc",
Flags: []cli.Flag{
flags.CertFlag,
flags.BeaconRPCProviderFlag,
flags.BeaconRESTApiHeaders,
flags.EnableRPCFlag,
flags.RPCHost,
flags.RPCPort,
flags.HTTPServerPort,
flags.HTTPServerHost,
flags.GRPCRetriesFlag,
flags.GRPCRetryDelayFlag,
flags.HTTPServerCorsDomain,
flags.GRPCHeadersFlag,
flags.BeaconRESTApiProviderFlag,
},
},
{
Name: "proposer",
Flags: []cli.Flag{
flags.ProposerSettingsFlag,
flags.ProposerSettingsURLFlag,
flags.SuggestedFeeRecipientFlag,
flags.EnableBuilderFlag,
flags.BuilderGasLimitFlag,
flags.ValidatorsRegistrationBatchSizeFlag,
flags.GraffitiFlag,
flags.GraffitiFileFlag,
},
},
{
Name: "remote signer",
Flags: []cli.Flag{
flags.Web3SignerURLFlag,
flags.Web3SignerPublicValidatorKeysFlag,
flags.Web3SignerKeyFileFlag,
},
},
{
Name: "slasher",
Flags: []cli.Flag{
flags.SlasherRPCProviderFlag,
flags.SlasherCertFlag,
},
},
{
Name: "misc",
Flags: []cli.Flag{
flags.DisablePenaltyRewardLogFlag,
flags.DisableAccountMetricsFlag,
flags.EnableDistributed,
flags.AuthTokenPathFlag,
flags.DisableDutiesPolling,
flags.MaxHealthChecksFlag,
},
},
{
Name: "features",
Flags: features.ActiveFlags(features.ValidatorFlags),
},
{
Name: "interop",
Flags: []cli.Flag{
flags.InteropNumValidators,
flags.InteropStartIndex,
},
},
{
Name: "deprecated",
Flags: []cli.Flag{},
},
}
func init() {
cli.AppHelpTemplate = appHelpTemplate
type helpData struct {
App any
FlagGroups []flagGroup
}
originalHelpPrinter := cli.HelpPrinter
cli.HelpPrinter = func(w io.Writer, tmpl string, data any) {
if tmpl == appHelpTemplate {
for _, group := range appHelpFlagGroups {
sort.Sort(cli.FlagsByName(group.Flags))
}
originalHelpPrinter(w, tmpl, helpData{data, appHelpFlagGroups})
} else {
originalHelpPrinter(w, tmpl, data)
}
}
}