Skip to content

Commit

Permalink
(#81) expand the state admin tool
Browse files Browse the repository at this point in the history
Now shows all matching entries and include filters based
on time, regex, advised etc to select those nodes.

Signed-off-by: R.I.Pienaar <[email protected]>
  • Loading branch information
ripienaar committed Feb 22, 2023
1 parent f6abd21 commit c3955fb
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 31 deletions.
150 changes: 128 additions & 22 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"os"
"os/signal"
"path/filepath"
"regexp"
"runtime"
"runtime/pprof"
"strings"
Expand Down Expand Up @@ -50,8 +51,11 @@ type cmd struct {
findSince time.Duration
findFollow bool
nCtx string
stateDir string
stateValue string
stateSource string
stateValue *regexp.Regexp
stateValuesOnly bool
stateAdvised bool
stateSince time.Duration
json bool
choriaToken string
choriaSeed string
Expand Down Expand Up @@ -89,8 +93,12 @@ func Run() {
admFind.Flag("choria-collective", "The Choria collective you will be connecting to").Default("choria").StringVar(&c.choriaCollective)

admState := admin.Commandf("state", "Search state files").Action(c.findState)
admState.Arg("dir", "Directory where state files are kept").Required().ExistingDirVar(&c.stateDir)
admState.Arg("value", "The value to search for").Required().StringVar(&c.stateValue)
admState.Arg("dir", "Directory where state files are kept").Required().StringVar(&c.stateSource)
admState.Flag("since", "List only entries seen since a certain duration ago").DurationVar(&c.stateSince)
admState.Flag("advised", "Include entries that are in warning state").Default("true").BoolVar(&c.stateAdvised)
admState.Flag("value", "A regular expression value to search for").RegexpVar(&c.stateValue)
admState.Flag("values", "List only values rather than full entries").BoolVar(&c.stateValuesOnly)
admState.Flag("json", "Render JSON values").BoolVar(&c.json)

admGossip := admin.Commandf("gossip", "View the synchronization traffic").Action(c.gossipAction)
admGossip.Flag("json", "Render JSON values").BoolVar(&c.json)
Expand All @@ -102,8 +110,10 @@ func Run() {
app.MustParseWithUsage(os.Args[1:])
}

func (c *cmd) findState(_ *fisk.ParseContext) error {
return filepath.WalkDir(c.stateDir, func(path string, d fs.DirEntry, err error) error {
func (c *cmd) findStateFiles(dir string) ([]string, error) {
var paths []string

err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
Expand All @@ -116,6 +126,34 @@ func (c *cmd) findState(_ *fisk.ParseContext) error {
return nil
}

paths = append(paths, path)

return nil
})

return paths, err
}

func (c *cmd) findState(_ *fisk.ParseContext) error {
var paths []string
var err error

if stat, err := os.Stat(c.stateSource); err == nil {
if !stat.IsDir() {
paths = append(paths, c.stateSource)
}
}

if len(paths) == 0 {
paths, err = c.findStateFiles(c.stateSource)
if err != nil {
return err
}
}

var selected []*idtrack.Item

for _, path := range paths {
items := idtrack.Tracker{}
sb, err := os.ReadFile(path)
if err != nil {
Expand All @@ -126,30 +164,98 @@ func (c *cmd) findState(_ *fisk.ParseContext) error {
return err
}

item, ok := items.Items[c.stateValue]
if ok {
fmt.Printf("%s:\n\n", path)
for v, item := range items.Items {
item.Value = v

fmt.Printf(" Value: %v\n", c.stateValue)
if item.Seen.IsZero() {
fmt.Printf(" Seen Time: never\n")
} else {
fmt.Printf(" Seen Time: %v (%v)\n", item.Seen, time.Since(item.Seen).Round(time.Second))
if c.stateSince > 0 && time.Since(item.Seen) >= c.stateSince {
continue
}

if item.Copied.IsZero() {
fmt.Printf(" Copied Time: never\n")
} else {
fmt.Printf(" Copied Time: %v (%v)\n", item.Copied, time.Since(item.Copied).Round(time.Second))
if !c.stateAdvised && item.Advised {
continue
}

if c.stateValue != nil && !c.stateValue.MatchString(item.Value) {
continue
}
fmt.Printf(" Payload Size: %v\n", item.Size)
fmt.Printf(" Advised: %t\n", item.Advised)

fmt.Println()
selected = append(selected, item)
}
}

if len(selected) == 0 {
if c.stateValuesOnly {
return nil
}
if c.json {
fmt.Println("[]")
return nil
}

fmt.Println("No items matched")
return nil
})
}

// just values used later should we need to json dump
var values []string

// avoid duplicate names though in practice one would partition on fqdn so there wouldnt be dupes but worth doing anyway
if c.stateValuesOnly {
uniq := []*idtrack.Item{}
seen := make(map[string]struct{})

for _, item := range selected {
if _, ok := seen[item.Value]; ok {
continue
}

uniq = append(uniq, item)
values = append(values, item.Value)
seen[item.Value] = struct{}{}
}

selected = uniq
}

if c.json {
v := any(selected)
if c.stateValuesOnly {
v = values
}

j, err := json.Marshal(v)
if err != nil {
return err
}
fmt.Println(string(j))
return nil
}

for _, item := range selected {
if c.stateValuesOnly {
fmt.Println(item.Value)
continue
}

fmt.Printf(" Value: %v\n", item.Value)
if item.Seen.IsZero() {
fmt.Printf(" Seen Time: never\n")
} else {
fmt.Printf(" Seen Time: %v (%v)\n", item.Seen, time.Since(item.Seen).Round(time.Second))
}

if item.Copied.IsZero() {
fmt.Printf(" Copied Time: never\n")
} else {
fmt.Printf(" Copied Time: %v (%v)\n", item.Copied, time.Since(item.Copied).Round(time.Second))
}
fmt.Printf(" Payload Size: %v\n", item.Size)
fmt.Printf(" Advised: %t\n", item.Advised)

fmt.Println()
}

return nil
}

func (c *cmd) connect() (*nats.Conn, error) {
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ require (
github.com/nats-io/jsm.go v0.0.35
github.com/nats-io/nats-server/v2 v2.9.14
github.com/nats-io/nats.go v1.23.0
github.com/onsi/ginkgo/v2 v2.8.1
github.com/onsi/gomega v1.26.0
github.com/onsi/ginkgo/v2 v2.8.3
github.com/onsi/gomega v1.27.1
github.com/prometheus/client_golang v1.14.0
github.com/segmentio/ksuid v1.0.4
github.com/sirupsen/logrus v1.9.0
Expand All @@ -24,7 +24,7 @@ require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/golang-jwt/jwt/v4 v4.4.3 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down Expand Up @@ -57,10 +57,10 @@ github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/onsi/ginkgo/v2 v2.8.1 h1:xFTEVwOFa1D/Ty24Ws1npBWkDYEV9BqZrsDxVrVkrrU=
github.com/onsi/ginkgo/v2 v2.8.1/go.mod h1:N1/NbDngAFcSLdyZ+/aYTYGSlq9qMCS/cNKGJjy+csc=
github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
github.com/onsi/gomega v1.26.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM=
github.com/onsi/ginkgo/v2 v2.8.3 h1:RpbK1G8nWPNaCVFBWsOGnEQQGgASi6b8fxcWBvDYjxQ=
github.com/onsi/ginkgo/v2 v2.8.3/go.mod h1:6OaUA8BCi0aZfmzYT/q9AacwTzDpNbxILUT+TlBq6MY=
github.com/onsi/gomega v1.27.1 h1:rfztXRbg6nv/5f+Raen9RcGoSecHIFgBBLQK3Wdj754=
github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfadcIAw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
Expand Down

0 comments on commit c3955fb

Please sign in to comment.