colored labels output for logcli (#2470)

* colored labels output for logcli

* add period to all cli description
pull/2483/head
Aditya C S 5 years ago committed by GitHub
parent 36164bbe1a
commit 68568f141e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      cmd/logcli/main.go
  2. 47
      docs/sources/getting-started/logcli.md
  3. 5
      pkg/logcli/output/default.go
  4. 43
      pkg/logcli/output/default_test.go
  5. 31
      pkg/logcli/output/output.go
  6. 2
      pkg/logcli/output/output_test.go
  7. 4
      pkg/logcli/query/query.go

@ -25,7 +25,6 @@ var (
statistics = app.Flag("stats", "Show query statistics").Default("false").Bool()
outputMode = app.Flag("output", "Specify output mode [default, raw, jsonl]. raw suppresses log labels and timestamp.").Default("default").Short('o').Enum("default", "raw", "jsonl")
timezone = app.Flag("timezone", "Specify the timezone to use when formatting output timestamps [Local, UTC]").Default("Local").Short('z').Enum("Local", "UTC")
cpuProfile = app.Flag("cpuprofile", "Specify the location for writing a CPU profile.").Default("").String()
memProfile = app.Flag("memprofile", "Specify the location for writing a memory profile.").Default("").String()
@ -119,8 +118,9 @@ func main() {
}
outputOptions := &output.LogOutputOptions{
Timezone: location,
NoLabels: rangeQuery.NoLabels,
Timezone: location,
NoLabels: rangeQuery.NoLabels,
ColoredOutput: rangeQuery.ColoredOutput,
}
out, err := output.NewLogOutput(*outputMode, outputOptions)
@ -140,8 +140,9 @@ func main() {
}
outputOptions := &output.LogOutputOptions{
Timezone: location,
NoLabels: instantQuery.NoLabels,
Timezone: location,
NoLabels: instantQuery.NoLabels,
ColoredOutput: instantQuery.ColoredOutput,
}
out, err := output.NewLogOutput(*outputMode, outputOptions)
@ -280,6 +281,7 @@ func newQuery(instant bool, cmd *kingpin.CmdClause) *query.Query {
cmd.Flag("include-label", "Include labels given the provided key during output.").StringsVar(&q.ShowLabelsKey)
cmd.Flag("labels-length", "Set a fixed padding to labels").Default("0").IntVar(&q.FixedLabelsLen)
cmd.Flag("store-config", "Execute the current query using a configured storage from a given Loki configuration file.").Default("").StringVar(&q.LocalConfig)
cmd.Flag("colored-output", "Show ouput with colored labels").Default("false").BoolVar(&q.ColoredOutput)
return q
}

@ -80,10 +80,10 @@ A command-line for loki.
Flags:
--help Show context-sensitive help (also try --help-long and --help-man).
--version Show application version.
-q, --quiet Suppress query metadata
--stats Show query statistics
-q, --quiet Suppress query metadata.
--stats Show query statistics.
-o, --output=default Specify output mode [default, raw, jsonl]. raw suppresses log labels and timestamp.
-z, --timezone=Local Specify the timezone to use when formatting output timestamps [Local, UTC]
-z, --timezone=Local Specify the timezone to use when formatting output timestamps [Local, UTC].
--cpuprofile="" Specify the location for writing a CPU profile.
--memprofile="" Specify the location for writing a memory profile.
--addr="http://localhost:3100"
@ -164,10 +164,10 @@ instead.
Flags:
--help Show context-sensitive help (also try --help-long and --help-man).
--version Show application version.
-q, --quiet Suppress query metadata
--stats Show query statistics
-q, --quiet Suppress query metadata.
--stats Show query statistics.
-o, --output=default Specify output mode [default, raw, jsonl]. raw suppresses log labels and timestamp.
-z, --timezone=Local Specify the timezone to use when formatting output timestamps [Local, UTC]
-z, --timezone=Local Specify the timezone to use when formatting output timestamps [Local, UTC].
--cpuprofile="" Specify the location for writing a CPU profile.
--memprofile="" Specify the location for writing a memory profile.
--addr="http://localhost:3100"
@ -182,22 +182,23 @@ Flags:
bypassing an auth gateway.
--limit=30 Limit on number of entries to print.
--since=1h Lookback window.
--from=FROM Start looking for logs at this absolute time (inclusive)
--to=TO Stop looking for logs at this absolute time (exclusive)
--from=FROM Start looking for logs at this absolute time (inclusive).
--to=TO Stop looking for logs at this absolute time (exclusive).
--step=STEP Query resolution step width, for metric queries. Evaluate the query at the specified step over the time
range.
--interval=INTERVAL Query interval, for log queries. Return entries at the specified interval, ignoring those between.
**This parameter is experimental, please see Issue 1779**
**This parameter is experimental, please see Issue 1779**.
--forward Scan forwards through logs.
--no-labels Do not print any labels
--no-labels Do not print any labels.
--exclude-label=EXCLUDE-LABEL ...
Exclude labels given the provided key during output.
--include-label=INCLUDE-LABEL ...
Include labels given the provided key during output.
--labels-length=0 Set a fixed padding to labels
--labels-length=0 Set a fixed padding to labels.
--store-config="" Execute the current query using a configured storage from a given Loki configuration file.
-t, --tail Tail the logs
--delay-for=0 Delay in tailing by number of seconds to accumulate logs for re-ordering
-t, --tail Tail the logs.
--delay-for=0 Delay in tailing by number of seconds to accumulate logs for re-ordering.
--colored-output Show ouput with colored labels.
Args:
<query> eg '{foo="bar",baz=~".*blip"} |~ ".*error.*"'
@ -210,10 +211,10 @@ Find values for a given label.
Flags:
--help Show context-sensitive help (also try --help-long and --help-man).
--version Show application version.
-q, --quiet Suppress query metadata
--stats Show query statistics
-q, --quiet Suppress query metadata.
--stats Show query statistics.
-o, --output=default Specify output mode [default, raw, jsonl]. raw suppresses log labels and timestamp.
-z, --timezone=Local Specify the timezone to use when formatting output timestamps [Local, UTC]
-z, --timezone=Local Specify the timezone to use when formatting output timestamps [Local, UTC].
--cpuprofile="" Specify the location for writing a CPU profile.
--memprofile="" Specify the location for writing a memory profile.
--addr="http://localhost:3100"
@ -227,8 +228,8 @@ Flags:
--org-id="" adds X-Scope-OrgID to API requests for representing tenant ID. Useful for requesting tenant data when
bypassing an auth gateway.
--since=1h Lookback window.
--from=FROM Start looking for labels at this absolute time (inclusive)
--to=TO Stop looking for labels at this absolute time (exclusive)
--from=FROM Start looking for labels at this absolute time (inclusive).
--to=TO Stop looking for labels at this absolute time (exclusive).
Args:
[<label>] The name of the label.
@ -241,10 +242,10 @@ Run series query.
Flags:
--help Show context-sensitive help (also try --help-long and --help-man).
--version Show application version.
-q, --quiet Suppress query metadata
--stats Show query statistics
-q, --quiet Suppress query metadata.
--stats Show query statistics.
-o, --output=default Specify output mode [default, raw, jsonl]. raw suppresses log labels and timestamp.
-z, --timezone=Local Specify the timezone to use when formatting output timestamps [Local, UTC]
-z, --timezone=Local Specify the timezone to use when formatting output timestamps [Local, UTC].
--cpuprofile="" Specify the location for writing a CPU profile.
--memprofile="" Specify the location for writing a memory profile.
--addr="http://localhost:3100"
@ -258,8 +259,8 @@ Flags:
--org-id="" adds X-Scope-OrgID to API requests for representing tenant ID. Useful for requesting tenant data when
bypassing an auth gateway.
--since=1h Lookback window.
--from=FROM Start looking for logs at this absolute time (inclusive)
--to=TO Stop looking for logs at this absolute time (exclusive)
--from=FROM Start looking for logs at this absolute time (inclusive).
--to=TO Stop looking for logs at this absolute time (exclusive).
--match=MATCH ... eg '{foo="bar",baz=~".*blip"}'
```

@ -24,6 +24,11 @@ func (o *DefaultOutput) Format(ts time.Time, lbls loghttp.LabelSet, maxLabelsLen
return fmt.Sprintf("%s %s", color.BlueString(timestamp), line)
}
if o.options.ColoredOutput {
labelsColor := getColor(lbls.String()).SprintFunc()
return fmt.Sprintf("%s %s %s", color.BlueString(timestamp), labelsColor(padLabel(lbls, maxLabelsLen)), line)
}
return fmt.Sprintf("%s %s %s", color.BlueString(timestamp), color.RedString(padLabel(lbls, maxLabelsLen)), line)
}

@ -132,6 +132,49 @@ func TestDefaultOutput_FormatLabelsPadding(t *testing.T) {
}
}
func TestColorForLabels(t *testing.T) {
tests := map[string]struct {
labels loghttp.LabelSet
otherLabels loghttp.LabelSet
expected bool
}{
"different labels": {
loghttp.LabelSet(map[string]string{
"type": "test",
"app": "loki",
}),
loghttp.LabelSet(map[string]string{
"type": "test",
"app": "grafana-loki",
}),
false,
},
"same labels": {
loghttp.LabelSet(map[string]string{
"type": "test",
"app": "loki",
}),
loghttp.LabelSet(map[string]string{
"type": "test",
"app": "loki",
}),
true,
},
}
for testName, testData := range tests {
testData := testData
t.Run(testName, func(t *testing.T) {
t.Parallel()
labelsColor := getColor(testData.labels.String())
otherLablesColor := getColor(testData.otherLabels.String())
assert.Equal(t, testData.expected, labelsColor.Equals(otherLablesColor))
})
}
}
func findMaxLabelsLength(labelsList []loghttp.LabelSet) int {
maxLabelsLen := 0

@ -2,11 +2,29 @@ package output
import (
"fmt"
"hash/fnv"
"time"
"github.com/fatih/color"
"github.com/grafana/loki/pkg/loghttp"
)
// Blue color is excluded since we are already printing timestamp
// in blue color
var colorList = []*color.Color{
color.New(color.FgHiCyan),
color.New(color.FgCyan),
color.New(color.FgHiGreen),
color.New(color.FgGreen),
color.New(color.FgHiMagenta),
color.New(color.FgMagenta),
color.New(color.FgHiYellow),
color.New(color.FgYellow),
color.New(color.FgHiRed),
color.New(color.FgRed),
}
// LogOutput is the interface any output mode must implement
type LogOutput interface {
Format(ts time.Time, lbls loghttp.LabelSet, maxLabelsLen int, line string) string
@ -14,8 +32,9 @@ type LogOutput interface {
// LogOutputOptions defines options supported by LogOutput
type LogOutputOptions struct {
Timezone *time.Location
NoLabels bool
Timezone *time.Location
NoLabels bool
ColoredOutput bool
}
// NewLogOutput creates a log output based on the input mode and options
@ -41,3 +60,11 @@ func NewLogOutput(mode string, options *LogOutputOptions) (LogOutput, error) {
return nil, fmt.Errorf("unknown log output mode '%s'", mode)
}
}
func getColor(labels string) *color.Color {
hash := fnv.New32()
hash.Write([]byte(labels))
id := hash.Sum32() % uint32(len(colorList))
color := colorList[id]
return color
}

@ -8,7 +8,7 @@ import (
)
func TestNewLogOutput(t *testing.T) {
options := &LogOutputOptions{time.UTC, false}
options := &LogOutputOptions{time.UTC, false, false}
out, err := NewLogOutput("default", options)
assert.NoError(t, err)

@ -51,8 +51,8 @@ type Query struct {
IgnoreLabelsKey []string
ShowLabelsKey []string
FixedLabelsLen int
LocalConfig string
ColoredOutput bool
LocalConfig string
}
// DoQuery executes the query and prints out the results

Loading…
Cancel
Save