mirror of
https://codeberg.org/scip/esctl.git
synced 2026-08-24 22:34:19 +02:00
Compare commits
3 Commits
feature/no
...
fix/node-s
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f230b5f02 | |||
| b7ac5733f1 | |||
| 4557fcca7b |
4
Makefile
4
Makefile
@@ -67,10 +67,10 @@ test: clean buildlocal
|
|||||||
|
|
||||||
testlint: test lint
|
testlint: test lint
|
||||||
|
|
||||||
lint-basic:
|
lint:
|
||||||
golangci-lint run --enable-only errcheck,govet,ineffassign,staticcheck,unused
|
golangci-lint run --enable-only errcheck,govet,ineffassign,staticcheck,unused
|
||||||
|
|
||||||
lint:
|
lint-full:
|
||||||
golangci-lint run --show-stats=false
|
golangci-lint run --show-stats=false
|
||||||
|
|
||||||
testfuzzy: clean
|
testfuzzy: clean
|
||||||
|
|||||||
@@ -538,7 +538,6 @@ index - manage indicies
|
|||||||
close - close an index
|
close - close an index
|
||||||
fields - show info about field capabilities
|
fields - show info about field capabilities
|
||||||
ilm - show ilm status
|
ilm - show ilm status
|
||||||
du - show index disk usage
|
|
||||||
alias - manage index aliases
|
alias - manage index aliases
|
||||||
create - create an index alias
|
create - create an index alias
|
||||||
list - list index aliases
|
list - list index aliases
|
||||||
@@ -556,7 +555,6 @@ node - manage nodes
|
|||||||
list - list nodes
|
list - list nodes
|
||||||
show - show details about a node
|
show - show details about a node
|
||||||
clients - show node http clients
|
clients - show node http clients
|
||||||
usage - show node usage stats
|
|
||||||
role - manage roles
|
role - manage roles
|
||||||
list - list roles
|
list - list roles
|
||||||
show - show details about a role
|
show - show details about a role
|
||||||
|
|||||||
@@ -91,12 +91,6 @@ func ApiRepl(conf *cfg.Config) *cli.Command {
|
|||||||
Aliases: []string{"p"},
|
Aliases: []string{"p"},
|
||||||
Sources: cli.EnvVars("PAGER", "ES_JSON_PAGER"),
|
Sources: cli.EnvVars("PAGER", "ES_JSON_PAGER"),
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "human-readable-cat",
|
|
||||||
Usage: "enable human readable /_cat output",
|
|
||||||
Destination: &conf.HumanCat,
|
|
||||||
Aliases: []string{"H"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||||
|
|||||||
17
cmd/node.go
17
cmd/node.go
@@ -36,7 +36,6 @@ func Node(conf *cfg.Config) *cli.Command {
|
|||||||
NodeList(conf),
|
NodeList(conf),
|
||||||
NodeShow(conf),
|
NodeShow(conf),
|
||||||
NodeClients(conf),
|
NodeClients(conf),
|
||||||
NodeUsage(conf),
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,19 +103,3 @@ func NodeClients(conf *cfg.Config) *cli.Command {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NodeUsage(conf *cfg.Config) *cli.Command {
|
|
||||||
return &cli.Command{
|
|
||||||
Name: "usage",
|
|
||||||
Usage: "show node usage stats",
|
|
||||||
UsageText: "usage [options] [<node>]",
|
|
||||||
|
|
||||||
ShellComplete: func(ctx context.Context, cmd *cli.Command) {
|
|
||||||
complete(conf, cmd, Cnode)
|
|
||||||
},
|
|
||||||
|
|
||||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
|
||||||
return es.NodeUsage(conf, cmd.Args().Get(0))
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -101,8 +101,7 @@ type Config struct {
|
|||||||
MaxDocs, MaxShardSize, MaxShardDocs int // roll over
|
MaxDocs, MaxShardSize, MaxShardDocs int // roll over
|
||||||
DryRun bool // rollover: -n
|
DryRun bool // rollover: -n
|
||||||
|
|
||||||
Tag string // api ls: -t
|
Tag string // api ls: -t
|
||||||
HumanCat bool // api repl: -H
|
|
||||||
|
|
||||||
Ilm Ilm // ilm create
|
Ilm Ilm // ilm create
|
||||||
|
|
||||||
|
|||||||
@@ -45,25 +45,22 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
intro = `# Input format: verb path [data]"
|
intro = `Input format: verb path [data]"
|
||||||
#
|
|
||||||
# Example:
|
Example:
|
||||||
#
|
|
||||||
# post /yourindex/_ccr/pause_follow
|
post /yourindex/_ccr/pause_follow
|
||||||
# put /yourindex/_settings {"number_of_replicas": 1}
|
put /yourindex/_settings {"number_of_replicas": 1}
|
||||||
#
|
|
||||||
# You can also put multiline JSON after the path like:
|
You can also put multiline JSON after the path like:
|
||||||
#
|
|
||||||
# put /yourindex/_settings
|
put /yourindex/_settings
|
||||||
# {
|
{
|
||||||
# "number_of_replicas": 1
|
"number_of_replicas": 1
|
||||||
# }
|
}
|
||||||
#
|
|
||||||
# If you do NOT supply a JSON in the first line, you need to hit ENTER
|
If you do NOT supply a JSON in the first line, you need to hit ENTER
|
||||||
# twice to complete.
|
twice to complete.`
|
||||||
#
|
|
||||||
# Supply the flag --human-readable-cat, -H to view /_cat API calls in
|
|
||||||
# human readable form.`
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// holds an API operation via go-openapi/spec
|
// holds an API operation via go-openapi/spec
|
||||||
@@ -146,11 +143,7 @@ func ApiRepl(conf *cfg.Config) error {
|
|||||||
fmt.Printf("failed to call API: %s\n", esErrorString(err))
|
fmt.Printf("failed to call API: %s\n", esErrorString(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf.HumanCat && strings.HasPrefix(parts[1], "/_cat") {
|
pageJsonOutput(conf, raw)
|
||||||
fmt.Println(string(raw))
|
|
||||||
} else {
|
|
||||||
pageJsonOutput(conf, raw)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:nilerr
|
//nolint:nilerr
|
||||||
@@ -223,10 +216,8 @@ func CallAPI(conf *cfg.Config, verb, path, data string) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !conf.HumanCat && strings.HasPrefix(path, "/_cat") {
|
req.Header.Add("Content-Type", "application/json")
|
||||||
req.Header.Add("Content-Type", "application/json")
|
req.Header.Add("Accept", "application/json")
|
||||||
req.Header.Add("Accept", "application/json")
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure we have got all we need
|
// make sure we have got all we need
|
||||||
if err := conf.DefaultCluster.CheckAuth(); err != nil {
|
if err := conf.DefaultCluster.CheckAuth(); err != nil {
|
||||||
@@ -280,8 +271,7 @@ func prettyfiJson(conf *cfg.Config, raw []byte) (string, error) {
|
|||||||
|
|
||||||
err := json.Indent(&pretty, raw, "", "\t")
|
err := json.Indent(&pretty, raw, "", "\t")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//nolint:nilerr
|
return "", fmt.Errorf("json parse error: %w", err)
|
||||||
return string(raw), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pretty.String(), nil
|
return pretty.String(), nil
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ func NodeList(conf *cfg.Config) error {
|
|||||||
|
|
||||||
slog.Debug("ES result", "nodes", nodes)
|
slog.Debug("ES result", "nodes", nodes)
|
||||||
|
|
||||||
table := printer.NewTableEmpty(conf).WithHeaders(
|
table := printer.NewTable(conf, 7, len(nodes))
|
||||||
"name", "ip", "load1m", "load5m", "load15m", "ram %", "heap %")
|
table.Addheaders("name", "ip", "load1m", "load5m", "load15m", "ram %", "heap %")
|
||||||
|
|
||||||
for _, node := range nodes {
|
for idx, node := range nodes {
|
||||||
table.AddRow(
|
table.Entries[idx] = []any{
|
||||||
*node.Name,
|
*node.Name,
|
||||||
*node.Ip,
|
*node.Ip,
|
||||||
*node.Load1M,
|
*node.Load1M,
|
||||||
@@ -49,7 +49,7 @@ func NodeList(conf *cfg.Config) error {
|
|||||||
*node.Load15M,
|
*node.Load15M,
|
||||||
node.RamPercent,
|
node.RamPercent,
|
||||||
node.HeapPercent,
|
node.HeapPercent,
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table.Sort()
|
table.Sort()
|
||||||
@@ -235,72 +235,3 @@ func NodeClients(conf *cfg.Config, nodename string) error {
|
|||||||
|
|
||||||
return table.Print()
|
return table.Print()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NodeUsage(conf *cfg.Config, nodeid string) error {
|
|
||||||
usage := conf.DefaultCluster.ES().Nodes.Usage()
|
|
||||||
|
|
||||||
if nodeid != "" {
|
|
||||||
usage.NodeId(nodeid)
|
|
||||||
}
|
|
||||||
|
|
||||||
stats, err := usage.Do(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to get node usage: %w", esErrorString(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
slog.Debug("ES result", "usage", stats)
|
|
||||||
|
|
||||||
table := printer.NewTableEmpty(conf).WithHeaders(
|
|
||||||
"node",
|
|
||||||
"bulk",
|
|
||||||
"doc get",
|
|
||||||
"doc mget",
|
|
||||||
"doc update",
|
|
||||||
"index doc",
|
|
||||||
"index stats",
|
|
||||||
"search",
|
|
||||||
"msearch",
|
|
||||||
"open pit",
|
|
||||||
)
|
|
||||||
|
|
||||||
for id, actions := range stats.Nodes {
|
|
||||||
node, err := getNodeName(conf, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
stat := actions.RestActions
|
|
||||||
|
|
||||||
table.AddRow(
|
|
||||||
node,
|
|
||||||
stat["bulk_action"],
|
|
||||||
stat["document_get_action"],
|
|
||||||
stat["document_mget_action"],
|
|
||||||
stat["document_update_action"],
|
|
||||||
stat["document_index_action"],
|
|
||||||
stat["indices_stats_action"],
|
|
||||||
stat["search_action"],
|
|
||||||
stat["msearch_action"],
|
|
||||||
stat["open_point_in_time"],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return table.Print()
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNodeName(conf *cfg.Config, id string) (string, error) {
|
|
||||||
res, err := conf.DefaultCluster.ES().Nodes.Info().
|
|
||||||
Metric("os").
|
|
||||||
Do(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to get node info: %w", esErrorString(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
for nodeid, node := range res.Nodes {
|
|
||||||
if id == nodeid {
|
|
||||||
return node.Name, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user