From 55a1005857528325b3cd4c4d18db235adefb6158 Mon Sep 17 00:00:00 2001 From: "T. von Dein" Date: Wed, 15 Jul 2026 14:52:30 +0200 Subject: [PATCH] add index template completion, index pattern filter and name filter (#95) --- cmd/completion.go | 3 +++ cmd/index_template.go | 21 ++++++++++++--- pkg/es/index_template.go | 54 +++++++++++++++++++++++++++++++++------ pkg/printer/metrics.go | 55 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 pkg/printer/metrics.go diff --git a/cmd/completion.go b/cmd/completion.go index ca647d0..cf6c1a8 100644 --- a/cmd/completion.go +++ b/cmd/completion.go @@ -34,6 +34,7 @@ const ( Cilm Cnode Cclustersettings + Cindextemplate ) func complete(conf *cfg.Config, cmd *cli.Command, what int) { @@ -65,6 +66,8 @@ func complete(conf *cfg.Config, cmd *cli.Command, what int) { list, err = es.NodeNames(conf) case Cclustersettings: list, err = es.ClusterSettingsNames(conf) + case Cindextemplate: + list, err = es.IndexTemplateNames(conf) } if err != nil { diff --git a/cmd/index_template.go b/cmd/index_template.go index 0dc2891..14aa8f0 100644 --- a/cmd/index_template.go +++ b/cmd/index_template.go @@ -49,8 +49,23 @@ func IndexTemplateList(conf *cfg.Config) *cli.Command { Aliases: []string{"ls"}, Usage: "list index templates", + Flags: []cli.Flag{ + &cli.StringSliceFlag{ + Name: "filter-index-pattern", + Usage: "show only index templates which use patterns, which match the filter", + Destination: &conf.Filter, + Aliases: []string{"F"}, + }, + &cli.BoolFlag{ + Name: "hidden", + Usage: "show hidden index templates as well", + Destination: &conf.Hidden, + Aliases: []string{"H"}, + }, + }, + Action: func(ctx context.Context, cmd *cli.Command) error { - return es.IndexTemplateList(conf) + return es.IndexTemplateList(conf, cmd.Args().Get(0)) }, } } @@ -71,7 +86,7 @@ func IndexTemplateShow(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(conf, cmd, Cindex) + complete(conf, cmd, Cindextemplate) }, } } @@ -215,7 +230,7 @@ func IndexTemplateDelete(conf *cfg.Config) *cli.Command { }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { - complete(conf, cmd, Cindex) + complete(conf, cmd, Cindextemplate) }, } } diff --git a/pkg/es/index_template.go b/pkg/es/index_template.go index 1eaed07..bc2dfa0 100644 --- a/pkg/es/index_template.go +++ b/pkg/es/index_template.go @@ -33,7 +33,23 @@ import ( ) // used for completion -func IndexTemplateList(conf *cfg.Config) error { +func IndexTemplateNames(conf *cfg.Config) ([]string, error) { + res, err := conf.DefaultCluster.ES().Indices.GetIndexTemplate(). + Do(context.Background()) + if err != nil { + return nil, fmt.Errorf("failed to get index templates: %w", esErrorString(err)) + } + + names := make([]string, len(res.IndexTemplates)) + + for idx, tpl := range res.IndexTemplates { + names[idx] = tpl.Name + } + + return names, nil +} + +func IndexTemplateList(conf *cfg.Config, filter string) error { res, err := conf.DefaultCluster.ES().Indices.GetIndexTemplate(). Do(context.Background()) if err != nil { @@ -42,20 +58,42 @@ func IndexTemplateList(conf *cfg.Config) error { slog.Debug("res", "index templates", res) - table := printer.NewTable(conf, 5, len(res.IndexTemplates)) - table.Addheaders("name", "description", "priority") + table := printer.NewTable(conf, 5, 0) + table.Addheaders("name", "description", "index patterns", "priority") - for idx, tpl := range res.IndexTemplates { - desc, err := json.Marshal(tpl.IndexTemplate.Meta_["description"]) - if err != nil { - return fmt.Errorf("failed to unmarshal meta json data: %w", err) + for _, tpl := range res.IndexTemplates { + if !conf.Hidden && strings.HasPrefix(tpl.Name, ".") { + continue } + if filter != "" && !strings.Contains(tpl.Name, filter) { + continue + } + + if len(conf.Filter) > 0 { + skip := true + + for _, filter := range conf.Filter { + for _, pattern := range tpl.IndexTemplate.IndexPatterns { + if strings.Contains(pattern, filter) { + skip = false + } + } + } + + if skip { + continue + } + } + + desc := strings.TrimPrefix(strings.TrimSuffix(string(tpl.IndexTemplate.Meta_["description"]), `"`), `"`) + var prio int64 if tpl.IndexTemplate.Priority != nil { prio = *tpl.IndexTemplate.Priority } - table.Entries[idx] = []any{tpl.Name, desc, prio} + + table.AddRow(tpl.Name, desc, tpl.IndexTemplate.IndexPatterns, prio) } table.Sort() diff --git a/pkg/printer/metrics.go b/pkg/printer/metrics.go new file mode 100644 index 0000000..caf5ed5 --- /dev/null +++ b/pkg/printer/metrics.go @@ -0,0 +1,55 @@ +/* +Copyright © 2026 Thomas von Dein + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +package printer + +import ( + "fmt" + "runtime/metrics" + "strconv" +) + +func printGoRoutineMetrics() { + fmt.Println("\nGoroutine metrics:") + printMetric("/sched/goroutines-created:goroutines", "Created") + printMetric("/sched/goroutines:goroutines", "Live") + printMetric("/sched/goroutines/not-in-go:goroutines", "Syscall/CGO") + printMetric("/sched/goroutines/runnable:goroutines", "Runnable") + printMetric("/sched/goroutines/running:goroutines", "Running") + printMetric("/sched/goroutines/waiting:goroutines", "Waiting") + + fmt.Println("Thread metrics:") + printMetric("/sched/gomaxprocs:threads", "Max") + printMetric("/sched/threads/total:threads", "Live") +} + +func printMetric(name string, descr string) { + sample := []metrics.Sample{{Name: name}} + metrics.Read(sample) + + var val string + + switch sample[0].Value.Kind() { + case metrics.KindFloat64, metrics.KindFloat64Histogram: + val = fmt.Sprintf("%.2f", sample[0].Value.Float64()) + case metrics.KindUint64: + val = strconv.FormatUint(sample[0].Value.Uint64(), 10) + case metrics.KindBad: + val = "n/a" + } + + fmt.Printf(" %s: %v\n", descr, val) +}