Skip to content

Commit

Permalink
humanlog: support force color mode with --color=yes
Browse files Browse the repository at this point in the history
For piping the output of humanlog to 'less -SR' and still getting nice
colors.
  • Loading branch information
samv authored and Antoine Grondin committed Jul 28, 2022
1 parent e548a43 commit 3c3631e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
14 changes: 13 additions & 1 deletion cmd/humanlog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ func newApp() *cli.App {
Value: humanlog.DefaultOptions.TruncateLength,
}

colorFlag := cli.StringFlag{
Name: "color",
Usage: "specify color mode: auto, on/force, off",
Value: "auto",
}

lightBg := cli.BoolFlag{
Name: "light-bg",
Usage: "use black as the base foreground color (for terminals with light backgrounds)",
Expand Down Expand Up @@ -119,7 +125,7 @@ func newApp() *cli.App {
app.Version = Version
app.Usage = "reads structured logs from stdin, makes them pretty on stdout!"

app.Flags = []cli.Flag{skipFlag, keepFlag, sortLongest, skipUnchanged, truncates, truncateLength, lightBg, timeFormat, ignoreInterrupts, messageFieldsFlag, timeFieldsFlag, levelFieldsFlag}
app.Flags = []cli.Flag{skipFlag, keepFlag, sortLongest, skipUnchanged, truncates, truncateLength, colorFlag, lightBg, timeFormat, ignoreInterrupts, messageFieldsFlag, timeFieldsFlag, levelFieldsFlag}

app.Action = func(c *cli.Context) error {

Expand All @@ -130,6 +136,10 @@ func newApp() *cli.App {
opts.TruncateLength = c.Int(truncateLength.Name)
opts.LightBg = c.BoolT(lightBg.Name)
opts.TimeFormat = c.String(timeFormat.Name)
var err error
if opts.ColorFlag, err = humanlog.GrokColorMode(c.String(colorFlag.Name)); err != nil {
fatalf(c, "bad --%s value: %s", colorFlag.Name, err.Error())
}

switch {
case c.IsSet(skipFlag.Name) && c.IsSet(keepFlag.Name):
Expand All @@ -156,6 +166,8 @@ func newApp() *cli.App {
signal.Ignore(os.Interrupt)
}

opts.ColorFlag.Apply()

log.Print("reading stdin...")
if err := humanlog.Scanner(os.Stdin, colorable.NewColorableStdout(), opts); err != nil {
log.Fatalf("scanning caught an error: %v", err)
Expand Down
37 changes: 37 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package humanlog

import (
"fmt"
"strings"
"time"

"github.com/fatih/color"
Expand All @@ -18,6 +20,7 @@ var DefaultOptions = &HandlerOptions{
SortLongest: true,
SkipUnchanged: true,
Truncates: true,
ColorFlag: ColorModeAuto,
LightBg: false,
TruncateLength: 15,
TimeFormat: time.Stamp,
Expand All @@ -43,6 +46,39 @@ var DefaultOptions = &HandlerOptions{
UnknownLevelColor: color.New(color.FgMagenta),
}

type ColorMode int

const (
ColorModeOff ColorMode = iota
ColorModeOn
ColorModeAuto
)

func GrokColorMode(colorMode string) (ColorMode, error) {
switch strings.ToLower(colorMode) {
case "on", "always", "force", "true", "yes", "1":
return ColorModeOn, nil
case "off", "never", "false", "no", "0":
return ColorModeOff, nil
case "auto", "tty", "maybe", "":
return ColorModeAuto, nil
default:
return ColorModeAuto, fmt.Errorf("'%s' is not a color mode (try 'on', 'off' or 'auto')", colorMode)
}
}

func (colorMode ColorMode) Apply() {
switch colorMode {
case ColorModeOff:
color.NoColor = true
case ColorModeOn:
color.NoColor = false
default:
// 'Auto' default is applied as a global variable initializer function, so nothing
// to do here.
}
}

type HandlerOptions struct {
Skip map[string]struct{}
Keep map[string]struct{}
Expand All @@ -55,6 +91,7 @@ type HandlerOptions struct {
SkipUnchanged bool
Truncates bool
LightBg bool
ColorFlag ColorMode
TruncateLength int
TimeFormat string

Expand Down

0 comments on commit 3c3631e

Please sign in to comment.