diff --git a/colors.go b/colors.go new file mode 100644 index 0000000..2ec2707 --- /dev/null +++ b/colors.go @@ -0,0 +1,22 @@ +package main + +import "github.com/fatih/color" + +var Colors = map[string]color.Attribute{ + "black": color.FgBlack, + "red": color.FgRed, + "green": color.FgGreen, + "yellow": color.FgYellow, + "blue": color.FgBlue, + "magenta": color.FgMagenta, + "cyan": color.FgCyan, + "white": color.FgWhite, + "hiblack": color.FgHiBlack, + "hired": color.FgHiRed, + "higreen": color.FgHiGreen, + "hiyellow": color.FgHiYellow, + "hiblue": color.FgHiBlue, + "himagenta": color.FgHiMagenta, + "hicyan": color.FgHiCyan, + "hiwhite": color.FgHiWhite, +} diff --git a/config.go b/config.go index 4bbf632..32c37df 100644 --- a/config.go +++ b/config.go @@ -8,7 +8,7 @@ import ( ) type SearchConfig struct { - Fields fieldList `arg:"-o,env:CLIBANA_FIELDS" help:"Comma-separated list of fields to output"` + Fields fieldList `arg:"-F,env:CLIBANA_FIELDS" help:"List of fields to output. Optionally, the field output color can be set" placeholder:"FIELD_NAME[:COLOR],..."` Follow bool `arg:"-f" help:"Enable live tailing of logs"` Query string `arg:"positional" default:"*" help:"Query string"` Start string `arg:"-s" default:"now-5m" help:"Start time"` @@ -48,17 +48,33 @@ func (ClibanaConfig) Description() string { } func (ClibanaConfig) Epilogue() string { - return "For more information, see https://github.com/ivoronin/clibana" + return strings.Join( + []string{ + "Supported color names:", + "black, red, green, yellow, blue, magenta, cyan, white", + "hiblack, hired, higreen, hiyellow, hiblue, himagenta, hicyan, hiwhite", + "", + "For more information, see https://github.com/ivoronin/clibana", + }, "\n") } func (ClibanaConfig) Version() string { return fmt.Sprintf("clibana %s (commit: %s, build date: %s)", version, commit, date) } -type fieldList []string +type fieldListItem struct { + Name string + Color string +} + +type fieldList []fieldListItem func (c *fieldList) UnmarshalText(text []byte) error { //nolint:unparam - *c = strings.Split(string(text), ",") + parts := strings.Split(string(text), ",") + for _, part := range parts { + name, color, _ := strings.Cut(part, ":") + *c = append(*c, fieldListItem{Name: name, Color: color}) + } return nil } diff --git a/go.mod b/go.mod index cafc30f..d73c361 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/aws/aws-sdk-go-v2 v1.30.3 github.com/aws/aws-sdk-go-v2/config v1.27.27 github.com/aws/aws-sdk-go-v2/service/opensearch v1.39.2 + github.com/fatih/color v1.17.0 github.com/opensearch-project/opensearch-go/v2 v2.3.0 ) @@ -23,4 +24,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.4 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.30.3 // indirect github.com/aws/smithy-go v1.20.3 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + golang.org/x/sys v0.18.0 // indirect ) diff --git a/go.sum b/go.sum index 189bc28..212d3a3 100644 --- a/go.sum +++ b/go.sum @@ -46,9 +46,16 @@ github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/opensearch-project/opensearch-go/v2 v2.3.0 h1:nQIEMr+A92CkhHrZgUhcfsrZjibvB3APXf2a1VwCmMQ= github.com/opensearch-project/opensearch-go/v2 v2.3.0/go.mod h1:8LDr9FCgUTVoT+5ESjc2+iaZuldqE+23Iq0r1XeNue8= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -78,8 +85,12 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/search.go b/search.go index 8cb480d..81010f5 100644 --- a/search.go +++ b/search.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/fatih/color" "github.com/opensearch-project/opensearch-go/v2" ) @@ -18,8 +19,12 @@ func search(client *opensearch.Client, clibanaConfig ClibanaConfig) { var values []string for _, field := range clibanaConfig.Search.Fields { - if strValue, ok := getNestedField(hit.Source, field); ok { - values = append(values, strValue) + if value, ok := getNestedField(hit.Source, field.Name); ok { + if colorCode, ok := Colors[field.Color]; ok { + colorer := color.New(colorCode) + value = colorer.Sprint(value) + } + values = append(values, value) } } diff --git a/tailer.go b/tailer.go index cc6a66e..c858aa6 100644 --- a/tailer.go +++ b/tailer.go @@ -96,7 +96,11 @@ func (t *Tailer) buildSearchRequestBody() *strings.Reader { } if len(t.ClibanaConfig.Search.Fields) > 0 { - query["_source"] = t.ClibanaConfig.Search.Fields + fieldNames := make([]string, 0, len(t.ClibanaConfig.Search.Fields)) + for _, field := range t.ClibanaConfig.Search.Fields { + fieldNames = append(fieldNames, field.Name) + } + query["_source"] = fieldNames } body, err := json.Marshal(query)