From 76ad6c7afac99bdb7257e9601125ed73ffb1d021 Mon Sep 17 00:00:00 2001 From: "T. von Dein" Date: Wed, 8 Jul 2026 14:13:47 +0200 Subject: [PATCH 1/4] remove workaround to load config in root.Before() (#83) see: https://github.com/urfave/cli/issues/2348 --- cmd/api.go | 2 +- cmd/ccr.go | 4 ++-- cmd/ccr_follower.go | 14 +++++++------- cmd/cluster.go | 2 +- cmd/cluster_reroute.go | 8 ++++---- cmd/cluster_settings.go | 2 +- cmd/completion.go | 9 +-------- cmd/datastream.go | 10 +++++----- cmd/ilm.go | 2 +- cmd/index.go | 10 +++++----- cmd/index_alias.go | 6 +++--- cmd/index_template.go | 4 ++-- cmd/node.go | 4 ++-- cmd/roles.go | 2 +- 14 files changed, 36 insertions(+), 43 deletions(-) diff --git a/cmd/api.go b/cmd/api.go index 5ccd5d0..beccd6f 100644 --- a/cmd/api.go +++ b/cmd/api.go @@ -72,7 +72,7 @@ func ApiShow(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Capi) + complete(conf, cmd, Capi) }, } } diff --git a/cmd/ccr.go b/cmd/ccr.go index 4eb536c..8a28c87 100644 --- a/cmd/ccr.go +++ b/cmd/ccr.go @@ -59,7 +59,7 @@ func CcrStatus(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Ccluster) + complete(conf, cmd, Ccluster) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -115,7 +115,7 @@ func CcrRemoteInfo(conf *cfg.Config) *cli.Command { UsageText: "info [options] []", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { diff --git a/cmd/ccr_follower.go b/cmd/ccr_follower.go index ea1c811..cd809dd 100644 --- a/cmd/ccr_follower.go +++ b/cmd/ccr_follower.go @@ -60,7 +60,7 @@ func CcrFollowerRenew(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -82,7 +82,7 @@ func CcrFollowerResume(conf *cfg.Config) *cli.Command { UsageText: "resume [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -104,7 +104,7 @@ func CcrFollowerPause(conf *cfg.Config) *cli.Command { UsageText: "pause [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -126,7 +126,7 @@ func CcrFollowerUnfollow(conf *cfg.Config) *cli.Command { UsageText: "unfollow [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -158,7 +158,7 @@ func CcrFollowerAdd(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -181,7 +181,7 @@ func CcrFollowerDelete(conf *cfg.Config) *cli.Command { UsageText: "delete ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -205,7 +205,7 @@ func CcrFollowerShow(conf *cfg.Config) *cli.Command { UsageText: "show ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { diff --git a/cmd/cluster.go b/cmd/cluster.go index fc3cbd6..1fdc445 100644 --- a/cmd/cluster.go +++ b/cmd/cluster.go @@ -83,7 +83,7 @@ func ClusterSwitch(conf *cfg.Config) *cli.Command { Aliases: []string{"ctx"}, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Ccluster) + complete(conf, cmd, Ccluster) }, Action: func(ctx context.Context, cmd *cli.Command) error { diff --git a/cmd/cluster_reroute.go b/cmd/cluster_reroute.go index 3518fb8..b5cb0ed 100644 --- a/cmd/cluster_reroute.go +++ b/cmd/cluster_reroute.go @@ -50,7 +50,7 @@ func ClusterRerouteMove(conf *cfg.Config) *cli.Command { UsageText: "move [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Flags: []cli.Flag{ @@ -95,7 +95,7 @@ func ClusterRerouteAllocateReplica(conf *cfg.Config) *cli.Command { UsageText: "allocate-replica [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Flags: []cli.Flag{ @@ -133,7 +133,7 @@ func ClusterRerouteCancel(conf *cfg.Config) *cli.Command { UsageText: "cancel [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Flags: []cli.Flag{ @@ -185,7 +185,7 @@ func ClusterRerouteAllocatePrimary(conf *cfg.Config, stale bool) *cli.Command { UsageText: name + " [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Flags: []cli.Flag{ diff --git a/cmd/cluster_settings.go b/cmd/cluster_settings.go index ccb45d1..dde3036 100644 --- a/cmd/cluster_settings.go +++ b/cmd/cluster_settings.go @@ -105,7 +105,7 @@ func ClusterSettingsSet(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cclustersettings) + complete(conf, cmd, Cclustersettings) }, Action: func(ctx context.Context, cmd *cli.Command) error { diff --git a/cmd/completion.go b/cmd/completion.go index 3862765..ca647d0 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -36,18 +36,11 @@ const ( Cclustersettings ) -func complete(cmd *cli.Command, what int) { +func complete(conf *cfg.Config, cmd *cli.Command, what int) { if cmd.NArg() > 0 { return } - // FIXME: config should load from root.Before(), see https://github.com/urfave/cli/issues/2348 - // workaround: load it directly here - conf := cfg.NewConfig() - if err := conf.Init(); err != nil { - return - } - var ( list []string err error diff --git a/cmd/datastream.go b/cmd/datastream.go index fbe067b..55be913 100644 --- a/cmd/datastream.go +++ b/cmd/datastream.go @@ -91,7 +91,7 @@ func DatastreamShow(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cdatastream) + complete(conf, cmd, Cdatastream) }, } } @@ -113,7 +113,7 @@ func DatastreamCreate(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cdatastream) + complete(conf, cmd, Cdatastream) }, } } @@ -135,7 +135,7 @@ func DatastreamDelete(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cdatastream) + complete(conf, cmd, Cdatastream) }, } } @@ -148,7 +148,7 @@ func DatastreamRollover(conf *cfg.Config) *cli.Command { UsageText: "rollover ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Flags: []cli.Flag{ @@ -205,7 +205,7 @@ func DatastreamIlm(conf *cfg.Config) *cli.Command { UsageText: "ds ilm ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cdatastream) + complete(conf, cmd, Cdatastream) }, Action: func(ctx context.Context, cmd *cli.Command) error { diff --git a/cmd/ilm.go b/cmd/ilm.go index e999de5..c10c5e1 100644 --- a/cmd/ilm.go +++ b/cmd/ilm.go @@ -123,7 +123,7 @@ func IlmShow(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cilm) + complete(conf, cmd, Cilm) }, } } diff --git a/cmd/index.go b/cmd/index.go index 03bb624..67f19e9 100644 --- a/cmd/index.go +++ b/cmd/index.go @@ -110,7 +110,7 @@ func IndexShow(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, } } @@ -180,7 +180,7 @@ func IndexDelete(conf *cfg.Config) *cli.Command { UsageText: "delete ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -201,7 +201,7 @@ func IndexClose(conf *cfg.Config) *cli.Command { UsageText: "close ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -243,7 +243,7 @@ func IndexFields(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -264,7 +264,7 @@ func IndexIlm(conf *cfg.Config) *cli.Command { UsageText: "index ilm ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { diff --git a/cmd/index_alias.go b/cmd/index_alias.go index b490f60..7d9ab02 100644 --- a/cmd/index_alias.go +++ b/cmd/index_alias.go @@ -52,7 +52,7 @@ func IndexAliasCreate(conf *cfg.Config) *cli.Command { UsageText: "create ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -76,7 +76,7 @@ func IndexAliasDelete(conf *cfg.Config) *cli.Command { UsageText: "delete ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -100,7 +100,7 @@ func IndexAliasRollover(conf *cfg.Config) *cli.Command { UsageText: "rollover ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, Flags: []cli.Flag{ diff --git a/cmd/index_template.go b/cmd/index_template.go index ae66d6e..0dc2891 100644 --- a/cmd/index_template.go +++ b/cmd/index_template.go @@ -71,7 +71,7 @@ func IndexTemplateShow(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, } } @@ -215,7 +215,7 @@ func IndexTemplateDelete(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cindex) + complete(conf, cmd, Cindex) }, } } diff --git a/cmd/node.go b/cmd/node.go index 46d62f1..9c34f64 100644 --- a/cmd/node.go +++ b/cmd/node.go @@ -60,7 +60,7 @@ func NodeShow(conf *cfg.Config) *cli.Command { UsageText: "show [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cnode) + complete(conf, cmd, Cnode) }, Action: func(ctx context.Context, cmd *cli.Command) error { @@ -90,7 +90,7 @@ func NodeClients(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Cnode) + complete(conf, cmd, Cnode) }, Action: func(ctx context.Context, cmd *cli.Command) error { diff --git a/cmd/roles.go b/cmd/roles.go index 8d4d480..519b62b 100644 --- a/cmd/roles.go +++ b/cmd/roles.go @@ -68,7 +68,7 @@ func RoleShow(conf *cfg.Config) *cli.Command { UsageText: "show [options] ", ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(cmd, Crole) + complete(conf, cmd, Crole) }, Action: func(ctx context.Context, cmd *cli.Command) error { From 068711589b16d869ede17557207634e9d6b1a6b1 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Wed, 8 Jul 2026 11:47:07 +0200 Subject: [PATCH 2/4] add more important node stats --- pkg/es/node.go | 35 +++++++++++++++++++++++++++++------ pkg/printer/bytes.go | 4 ++-- pkg/printer/cast.go | 4 ++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/pkg/es/node.go b/pkg/es/node.go index 89ebf0a..f9a377a 100644 --- a/pkg/es/node.go +++ b/pkg/es/node.go @@ -134,18 +134,41 @@ func NodeShow(conf *cfg.Config, nodename string) error { stat.Os.Cpu.LoadAverage["1m"], )}, {"Open FD's", *stat.Process.OpenFileDescriptors}, - {"Response time avg", fmt.Sprintf("%dns", *stat.AdaptiveSelection[id].AvgResponseTimeNs)}, + {"HTTP sesssions current/total", fmt.Sprintf("%d/%d", + *stat.Http.CurrentOpen, + *stat.Http.TotalOpened, + )}, + {"Traffic rx/tx", + printer.Bytes(*stat.Transport.RxSizeInBytes).String() + " / " + printer.Bytes(*stat.Transport.TxSizeInBytes).String()}, + {"Response time avg", time.Duration(*stat.AdaptiveSelection[id].AvgResponseTimeNs)}, {"Memory usage (used/avail)", humanize.Bytes(uint64(*stat.Os.Mem.UsedInBytes)) + " / " + humanize.Bytes(uint64(*stat.Os.Mem.TotalInBytes))}, + {"Search queries current/total", fmt.Sprintf("%d/%d", + stat.Indices.Search.QueryCurrent, + stat.Indices.Search.QueryTotal, + )}, + {"Search efficiency", stat.Indices.Search.QueryTimeInMillis / stat.Indices.Search.QueryTotal}, + {"Docs count", stat.Indices.Docs.Count}, + {"Merges current/total", fmt.Sprintf("%d/%d", + stat.Indices.Merges.Current, + stat.Indices.Merges.Total, + )}, + {"Merge docs count current/total", fmt.Sprintf("%d/%d", + stat.Indices.Merges.CurrentDocs, + stat.Indices.Merges.TotalDocs, + )}, + {"Merge size current/total", fmt.Sprintf("%s/%s", + printer.Bytes(stat.Indices.Merges.CurrentSizeInBytes).String(), + printer.Bytes(stat.Indices.Merges.TotalSizeInBytes).String(), + )}, + {"CircuitBreaker trip count", *stat.Breakers["fielddata"].Tripped}, } if len(stat.Fs.Data) > 0 { fs := stat.Fs.Data[0] - table.Entries = append(table.Entries, [][]any{ - {"Storage usage (used/avail)", - humanize.Bytes(uint64(*fs.AvailableInBytes)) + " / " + humanize.Bytes(uint64(*fs.TotalInBytes))}, - {"Storage mount", *fs.Mount}, - }...) + table.AddRow("Storage usage (used/avail)", + printer.Bytes(*fs.AvailableInBytes).String()+" / "+printer.Bytes(*fs.TotalInBytes).String()) + table.AddRow("Storage mount", *fs.Mount) } if err := table.Print(); err != nil { diff --git a/pkg/printer/bytes.go b/pkg/printer/bytes.go index cae3c58..6408f2c 100644 --- a/pkg/printer/bytes.go +++ b/pkg/printer/bytes.go @@ -22,8 +22,8 @@ type ByteSize struct { size uint64 } -func Bytes(size int64) ByteSize { - return ByteSize{size: uint64(size)} +func Bytes(size int64) *ByteSize { + return &ByteSize{size: uint64(size)} } func (b *ByteSize) String() string { diff --git a/pkg/printer/cast.go b/pkg/printer/cast.go index 8a3c27d..039b90a 100644 --- a/pkg/printer/cast.go +++ b/pkg/printer/cast.go @@ -38,12 +38,16 @@ func any2string(in any) string { return strconv.Itoa(val) case float64: return fmt.Sprintf("%.2f", val) + case float32: + return fmt.Sprintf("%.2f", val) case []string: return strings.Join(val, ",") case ByteSize: return val.String() case time.Time: return val.Format("2006-01-02 15:04:05") + case time.Duration: + return val.String() case []byte: return string(val) case nil: From c554b2a6cbfbecb6eac1d819e6e9c6b055d0b166 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Wed, 8 Jul 2026 13:44:45 +0200 Subject: [PATCH 3/4] add printer.ByteString() as shortcut --- pkg/es/node.go | 14 ++++++++------ pkg/printer/bytes.go | 9 +++++++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pkg/es/node.go b/pkg/es/node.go index f9a377a..84c10b5 100644 --- a/pkg/es/node.go +++ b/pkg/es/node.go @@ -26,7 +26,6 @@ import ( "codeberg.org/scip/esctl/pkg/cfg" "codeberg.org/scip/esctl/pkg/printer" - "github.com/dustin/go-humanize" ) func NodeList(conf *cfg.Config) error { @@ -126,6 +125,9 @@ func NodeShow(conf *cfg.Config, nodename string) error { {"OS", info.Os.PrettyName + " " + info.Os.Version}, {"Node roles", roles}, {"Node version", info.Version}, + // FIXME: not implementet upstream + // see: https://github.com/elastic/go-elasticsearch/issues/1526 + //{"Allocated shards", stat.Allocations.XXX}, {"HTTP clients", *stat.Http.CurrentOpen}, {"CPUs", *info.Os.AllocatedProcessors}, {"Load 15m/5m/1m", fmt.Sprintf("%.2f/%.2f/%.2f", @@ -139,10 +141,10 @@ func NodeShow(conf *cfg.Config, nodename string) error { *stat.Http.TotalOpened, )}, {"Traffic rx/tx", - printer.Bytes(*stat.Transport.RxSizeInBytes).String() + " / " + printer.Bytes(*stat.Transport.TxSizeInBytes).String()}, + printer.ByteString(*stat.Transport.RxSizeInBytes) + " / " + printer.ByteString(*stat.Transport.TxSizeInBytes)}, {"Response time avg", time.Duration(*stat.AdaptiveSelection[id].AvgResponseTimeNs)}, {"Memory usage (used/avail)", - humanize.Bytes(uint64(*stat.Os.Mem.UsedInBytes)) + " / " + humanize.Bytes(uint64(*stat.Os.Mem.TotalInBytes))}, + printer.ByteString(*stat.Os.Mem.UsedInBytes) + " / " + printer.ByteString(*stat.Os.Mem.TotalInBytes)}, {"Search queries current/total", fmt.Sprintf("%d/%d", stat.Indices.Search.QueryCurrent, stat.Indices.Search.QueryTotal, @@ -158,8 +160,8 @@ func NodeShow(conf *cfg.Config, nodename string) error { stat.Indices.Merges.TotalDocs, )}, {"Merge size current/total", fmt.Sprintf("%s/%s", - printer.Bytes(stat.Indices.Merges.CurrentSizeInBytes).String(), - printer.Bytes(stat.Indices.Merges.TotalSizeInBytes).String(), + printer.ByteString(stat.Indices.Merges.CurrentSizeInBytes), + printer.ByteString(stat.Indices.Merges.TotalSizeInBytes), )}, {"CircuitBreaker trip count", *stat.Breakers["fielddata"].Tripped}, } @@ -167,7 +169,7 @@ func NodeShow(conf *cfg.Config, nodename string) error { if len(stat.Fs.Data) > 0 { fs := stat.Fs.Data[0] table.AddRow("Storage usage (used/avail)", - printer.Bytes(*fs.AvailableInBytes).String()+" / "+printer.Bytes(*fs.TotalInBytes).String()) + printer.ByteString(*fs.AvailableInBytes)+" / "+printer.ByteString(*fs.TotalInBytes)) table.AddRow("Storage mount", *fs.Mount) } diff --git a/pkg/printer/bytes.go b/pkg/printer/bytes.go index 6408f2c..87cac11 100644 --- a/pkg/printer/bytes.go +++ b/pkg/printer/bytes.go @@ -22,10 +22,15 @@ type ByteSize struct { size uint64 } +func (b *ByteSize) String() string { + return humanize.Bytes(b.size) +} + func Bytes(size int64) *ByteSize { return &ByteSize{size: uint64(size)} } -func (b *ByteSize) String() string { - return humanize.Bytes(b.size) +func ByteString(size int64) string { + b := ByteSize{size: uint64(size)} + return b.String() } From 1f96fb9ab3bbd180753ac6688fdc77266e7cfcb7 Mon Sep 17 00:00:00 2001 From: Thomas von Dein Date: Wed, 8 Jul 2026 13:56:55 +0200 Subject: [PATCH 4/4] typo --- pkg/es/node.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/es/node.go b/pkg/es/node.go index 84c10b5..1b42d36 100644 --- a/pkg/es/node.go +++ b/pkg/es/node.go @@ -125,7 +125,7 @@ func NodeShow(conf *cfg.Config, nodename string) error { {"OS", info.Os.PrettyName + " " + info.Os.Version}, {"Node roles", roles}, {"Node version", info.Version}, - // FIXME: not implementet upstream + // FIXME: not implemented upstream // see: https://github.com/elastic/go-elasticsearch/issues/1526 //{"Allocated shards", stat.Allocations.XXX}, {"HTTP clients", *stat.Http.CurrentOpen},