Skip to content

Commit

Permalink
Disable colors on mimirtool's output when no terminal is detected (#9423
Browse files Browse the repository at this point in the history
)

* Disable colored output on mimirtool if no terminal is detected

* Add vendored files

* Update changelog

* Update CHANGELOG.md

* Update CHANGELOG.md

---------

Co-authored-by: Nick Pillitteri <[email protected]>
  • Loading branch information
jadolg and 56quarters authored Sep 26, 2024
1 parent bfca002 commit ebb6230
Show file tree
Hide file tree
Showing 42 changed files with 3,848 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@

### Mimirtool

* [CHANGE] Disable colored output on mimirtool when the output is not to a terminal. #9423
* [CHANGE] Add `--force-color` flag to be able to enable colored output when the output is not to a terminal. #9423
* [CHANGE] Analyze Rules: Count recording rules used in rules group as used. #6133
* [CHANGE] Remove deprecated `--rule-files` flag in favor of CLI arguments for the following commands: #8701
* `mimirtool rules load`
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ require (
go.opentelemetry.io/otel/trace v1.30.0
go.uber.org/multierr v1.11.0
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0
golang.org/x/term v0.24.0
google.golang.org/api v0.196.0
google.golang.org/protobuf v1.34.2
sigs.k8s.io/kustomize/kyaml v0.16.0
Expand Down
8 changes: 6 additions & 2 deletions pkg/mimirtool/commands/alerts.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
log "github.com/sirupsen/logrus"
"golang.org/x/term"

"github.com/grafana/mimir/pkg/mimirtool/client"
"github.com/grafana/mimir/pkg/mimirtool/printer"
Expand All @@ -43,6 +44,7 @@ type AlertmanagerCommand struct {
AlertmanagerConfigFile string
TemplateFiles []string
DisableColor bool
ForceColor bool
ValidateOnly bool
OutputDir string
UTF8StrictMode bool
Expand Down Expand Up @@ -81,6 +83,7 @@ func (a *AlertmanagerCommand) Register(app *kingpin.Application, envVars EnvVarN
// Get Alertmanager Configs Command
getAlertsCmd := alertCmd.Command("get", "Get the Alertmanager configuration that is currently in the Grafana Mimir Alertmanager.").Action(a.getConfig)
getAlertsCmd.Flag("disable-color", "disable colored output").BoolVar(&a.DisableColor)
getAlertsCmd.Flag("force-color", "force colored output").BoolVar(&a.ForceColor)
getAlertsCmd.Flag("output-dir", "The directory where the config and templates will be written to and disables printing to console.").ExistingDirVar(&a.OutputDir)

deleteCmd := alertCmd.Command("delete", "Delete the Alertmanager configuration that is currently in the Grafana Mimir Alertmanager.").Action(a.deleteConfig)
Expand All @@ -98,6 +101,7 @@ func (a *AlertmanagerCommand) Register(app *kingpin.Application, envVars EnvVarN
migrateCmd.Arg("config", "Alertmanager configuration file to load").Required().StringVar(&a.AlertmanagerConfigFile)
migrateCmd.Arg("template-files", "The template files to load").ExistingFilesVar(&a.TemplateFiles)
migrateCmd.Flag("disable-color", "disable colored output").BoolVar(&a.DisableColor)
migrateCmd.Flag("force-color", "force colored output").BoolVar(&a.ForceColor)
migrateCmd.Flag("output-dir", "The directory where the migrated configuration and templates will be written to and disables printing to console.").ExistingDirVar(&a.OutputDir)

verifyalertCmd := alertCmd.Command("verify", "Verify Alertmanager tenant configuration and template files.").Action(a.verifyAlertmanagerConfig)
Expand Down Expand Up @@ -153,7 +157,7 @@ func (a *AlertmanagerCommand) getConfig(_ *kingpin.ParseContext) error {
}

if a.OutputDir == "" {
p := printer.New(a.DisableColor)
p := printer.New(a.DisableColor, a.ForceColor, term.IsTerminal(int(os.Stdout.Fd())))
return p.PrintAlertmanagerConfig(cfg, templates)
}
return a.outputAlertManagerConfigTemplates(cfg, templates)
Expand Down Expand Up @@ -253,7 +257,7 @@ func (a *AlertmanagerCommand) migrateConfig(_ *kingpin.ParseContext) error {
return fmt.Errorf("failed to migrate cfg: %w", err)
}
if a.OutputDir == "" {
p := printer.New(a.DisableColor)
p := printer.New(a.DisableColor, a.ForceColor, term.IsTerminal(int(os.Stdout.Fd())))
return p.PrintAlertmanagerConfig(cfg, templates)
}
return a.outputAlertManagerConfigTemplates(cfg, templates)
Expand Down
14 changes: 10 additions & 4 deletions pkg/mimirtool/commands/rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/prometheus/model/rulefmt"
log "github.com/sirupsen/logrus"
"golang.org/x/term"
yamlv3 "gopkg.in/yaml.v3"

"github.com/grafana/mimir/pkg/mimirtool/client"
Expand Down Expand Up @@ -107,6 +108,7 @@ type RuleCommand struct {
Format string

DisableColor bool
ForceColor bool

// Diff Rules Config
Verbose bool
Expand Down Expand Up @@ -206,12 +208,14 @@ func (r *RuleCommand) Register(app *kingpin.Application, envVars EnvVarNames, re

// Print Rules Command
printRulesCmd.Flag("disable-color", "disable colored output").BoolVar(&r.DisableColor)
printRulesCmd.Flag("force-color", "force colored output").BoolVar(&r.ForceColor)
printRulesCmd.Flag("output-dir", "The directory where the rules will be written to.").ExistingDirVar(&r.OutputDir)

// Get RuleGroup Command
getRuleGroupCmd.Arg("namespace", "Namespace of the rulegroup to retrieve.").Required().StringVar(&r.Namespace)
getRuleGroupCmd.Arg("group", "Name of the rulegroup to retrieve.").Required().StringVar(&r.RuleGroup)
getRuleGroupCmd.Flag("disable-color", "disable colored output").BoolVar(&r.DisableColor)
getRuleGroupCmd.Flag("force-color", "force colored output").BoolVar(&r.ForceColor)
getRuleGroupCmd.Flag("output-dir", "The directory where the rules will be written to.").ExistingDirVar(&r.OutputDir)

// Delete RuleGroup Command
Expand All @@ -232,6 +236,7 @@ func (r *RuleCommand) Register(app *kingpin.Application, envVars EnvVarNames, re
"Comma separated list of paths to directories containing rules yaml files. Each file in a directory with a .yml or .yaml suffix will be parsed.",
).StringVar(&r.RuleFilesPath)
diffRulesCmd.Flag("disable-color", "disable colored output").BoolVar(&r.DisableColor)
diffRulesCmd.Flag("force-color", "force colored output").BoolVar(&r.ForceColor)
diffRulesCmd.Flag("verbose", "show diff output with rules changes").BoolVar(&r.Verbose)

// Sync Command
Expand Down Expand Up @@ -281,6 +286,7 @@ func (r *RuleCommand) Register(app *kingpin.Application, envVars EnvVarNames, re
// List Command
listCmd.Flag("format", "Backend type to interact with: <json|yaml|table>").Default("table").EnumVar(&r.Format, formats...)
listCmd.Flag("disable-color", "disable colored output").BoolVar(&r.DisableColor)
listCmd.Flag("force-color", "force colored output").BoolVar(&r.ForceColor)

// Delete Namespace Command
deleteNamespaceCmd.Arg("namespace", "Namespace to delete.").Required().StringVar(&r.Namespace)
Expand Down Expand Up @@ -383,7 +389,7 @@ func (r *RuleCommand) listRules(_ *kingpin.ParseContext) error {

}

p := printer.New(r.DisableColor)
p := printer.New(r.DisableColor, r.ForceColor, term.IsTerminal(int(os.Stdout.Fd())))
return p.PrintRuleSet(rules, r.Format, os.Stdout)
}

Expand All @@ -397,7 +403,7 @@ func (r *RuleCommand) printRules(_ *kingpin.ParseContext) error {
log.Fatalf("Unable to read rules from Grafana Mimir, %v", err)
}

p := printer.New(r.DisableColor)
p := printer.New(r.DisableColor, r.ForceColor, term.IsTerminal(int(os.Stdout.Fd())))

if r.OutputDir != "" {
log.Infof("Output dir detected writing rules to directory: %s", r.OutputDir)
Expand Down Expand Up @@ -456,7 +462,7 @@ func (r *RuleCommand) getRuleGroup(_ *kingpin.ParseContext) error {
return err
}

p := printer.New(r.DisableColor)
p := printer.New(r.DisableColor, r.ForceColor, term.IsTerminal(int(os.Stdout.Fd())))
return p.PrintRuleGroup(*group)
}

Expand Down Expand Up @@ -591,7 +597,7 @@ func (r *RuleCommand) diffRules(_ *kingpin.ParseContext) error {
})
}

p := printer.New(r.DisableColor)
p := printer.New(r.DisableColor, r.ForceColor, term.IsTerminal(int(os.Stdout.Fd())))
return p.PrintComparisonResult(changes, r.Verbose)
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/mimirtool/printer/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ type Printer struct {
}

// New returns a Printer struct
func New(color bool) *Printer {
func New(disableColor bool, forceColor bool, isTTY bool) *Printer {
return &Printer{
disableColor: color,
disableColor: !forceColor && (disableColor || !isTTY),
colorizer: colorstring.Colorize{
Colors: colorstring.DefaultColors,
Reset: true,
Disable: color,
Disable: !forceColor && (disableColor || !isTTY),
},
}
}
Expand Down
40 changes: 39 additions & 1 deletion pkg/mimirtool/printer/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ test-namespace-2 | test-rulegroup-d
name string
giveDisableColor bool
giveFormat string
giveIsTTY bool
giveForceColor bool
wantOutput string
}{
{
Expand All @@ -69,8 +71,22 @@ test-namespace-2 | test-rulegroup-d
{
name: "prints colorful json",
giveFormat: "json",
giveIsTTY: true,
wantOutput: wantColoredJSONBuffer.String(),
},
{
name: "prints colorless json on non-tty",
giveFormat: "json",
giveIsTTY: false,
wantOutput: wantJSONOutput,
},
{
name: "prints colorful json on non-tty with forced colors",
giveFormat: "json",
giveIsTTY: false,
giveForceColor: true,
wantOutput: wantColoredJSONBuffer.String(),
},
{
name: "prints colorless yaml",
giveDisableColor: true,
Expand All @@ -80,8 +96,30 @@ test-namespace-2 | test-rulegroup-d
{
name: "prints colorful yaml",
giveFormat: "yaml",
giveIsTTY: true,
wantOutput: wantColoredYAMLBuffer.String(),
},
{
name: "prints colorful yaml on non-tty with forced colors",
giveFormat: "yaml",
giveIsTTY: false,
giveForceColor: true,
wantOutput: wantColoredYAMLBuffer.String(),
},
{
name: "prints colorful yaml on tty with forced colors even if colors are disabled",
giveFormat: "yaml",
giveIsTTY: true,
giveDisableColor: true,
giveForceColor: true,
wantOutput: wantColoredYAMLBuffer.String(),
},
{
name: "prints colorless yaml on non-tty",
giveFormat: "yaml",
giveIsTTY: false,
wantOutput: wantYAMLOutput,
},
{
name: "defaults to tabwriter",
giveDisableColor: true,
Expand All @@ -93,7 +131,7 @@ test-namespace-2 | test-rulegroup-d
t.Run(tt.name, func(tst *testing.T) {
var b bytes.Buffer

p := New(tt.giveDisableColor)
p := New(tt.giveDisableColor, tt.giveForceColor, tt.giveIsTTY)
err := p.PrintRuleSet(giveRules, tt.giveFormat, &b)

require.NoError(tst, err)
Expand Down
8 changes: 8 additions & 0 deletions vendor/golang.org/x/sys/plan9/asm.s

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions vendor/golang.org/x/sys/plan9/asm_plan9_386.s

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions vendor/golang.org/x/sys/plan9/asm_plan9_amd64.s

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions vendor/golang.org/x/sys/plan9/asm_plan9_arm.s

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ebb6230

Please sign in to comment.