diff options
Diffstat (limited to 'examples/stats-client/stats_api.go')
-rw-r--r-- | examples/stats-client/stats_api.go | 133 |
1 files changed, 108 insertions, 25 deletions
diff --git a/examples/stats-client/stats_api.go b/examples/stats-client/stats_api.go index 288caea..562c2f9 100644 --- a/examples/stats-client/stats_api.go +++ b/examples/stats-client/stats_api.go @@ -19,13 +19,14 @@ import ( "fmt" "log" "os" + "strconv" "strings" "time" - "git.fd.io/govpp.git/adapter" - "git.fd.io/govpp.git/adapter/statsclient" - "git.fd.io/govpp.git/api" - "git.fd.io/govpp.git/core" + "go.fd.io/govpp/adapter" + "go.fd.io/govpp/adapter/statsclient" + "go.fd.io/govpp/api" + "go.fd.io/govpp/core" ) // ------------------------------------------------------------------ @@ -39,11 +40,12 @@ var ( statsSocket = flag.String("socket", statsclient.DefaultSocketName, "Path to VPP stats socket") dumpAll = flag.Bool("all", false, "Dump all stats including ones with zero values") pollPeriod = flag.Duration("period", time.Second*5, "Polling interval period") + async = flag.Bool("async", false, "Use asynchronous connection") ) func init() { flag.Usage = func() { - fmt.Fprintf(os.Stderr, "%s: usage [ls|dump|poll|errors|interfaces|nodes|system|buffers] <patterns>...\n", os.Args[0]) + fmt.Fprintf(os.Stderr, "%s: usage [ls|dump|poll|errors|interfaces|nodes|system|buffers|memory|epoch] <patterns/index>...\n", os.Args[0]) flag.PrintDefaults() os.Exit(1) } @@ -53,16 +55,46 @@ func main() { flag.Parse() skipZeros := !*dumpAll - var patterns []string + patterns := make([]string, 0) + indexes := make([]uint32, 0) if flag.NArg() > 0 { - patterns = flag.Args()[1:] + for _, arg := range flag.Args()[1:] { + if index, err := strconv.Atoi(arg); err == nil { + indexes = append(indexes, uint32(index)) + continue + } + patterns = append(patterns, arg) + } } - client := statsclient.NewStatsClient(*statsSocket) - - c, err := core.ConnectStats(client) - if err != nil { - log.Fatalln("Connecting failed:", err) + var ( + client *statsclient.StatsClient + c *core.StatsConnection + err error + ) + + if *async { + var statsChan chan core.ConnectionEvent + client = statsclient.NewStatsClient(*statsSocket, statsclient.SetSocketRetryPeriod(1*time.Second), + statsclient.SetSocketRetryTimeout(10*time.Second)) + c, statsChan, err = core.AsyncConnectStats(client, core.DefaultMaxReconnectAttempts, core.DefaultReconnectInterval) + if err != nil { + log.Fatalln("Asynchronous connecting failed:", err) + } + select { + case e := <-statsChan: + if e.State == core.Connected { + // OK + } else { + log.Fatalf("VPP stats asynchronous connection failed: %s\n", e.State.String()) + } + } + } else { + client = statsclient.NewStatsClient(*statsSocket) + c, err = core.ConnectStats(client) + if err != nil { + log.Fatalln("Connecting failed:", err) + } } defer c.Disconnect() @@ -114,10 +146,15 @@ func main() { } n := 0 for _, counter := range stats.Errors { - if skipZeros && counter.Value == 0 { + var sum uint32 + for _, valuePerWorker := range counter.Values { + sum += uint32(valuePerWorker) + } + + if skipZeros && sum == 0 { continue } - fmt.Printf(" - %v\n", counter) + fmt.Printf(" - %v %d (per worker: %v)\n", counter.CounterName, sum, counter.Values) n++ } fmt.Printf("Listed %d (%d) error counters\n", n, len(stats.Errors)) @@ -129,10 +166,17 @@ func main() { } fmt.Printf("Buffer stats: %+v\n", stats) + case "memory": + stats := new(api.MemoryStats) + if err := c.GetMemoryStats(stats); err != nil { + log.Fatalln("getting memory stats failed:", err) + } + fmt.Printf("Memory stats: %+v\n", stats) + case "dump": fmt.Printf("Dumping stats.. %s\n", strings.Join(patterns, " ")) - dumpStats(client, patterns, skipZeros) + dumpStats(client, patterns, indexes, skipZeros) case "poll": fmt.Printf("Polling stats.. %s\n", strings.Join(patterns, " ")) @@ -142,30 +186,69 @@ func main() { case "list", "ls", "": fmt.Printf("Listing stats.. %s\n", strings.Join(patterns, " ")) - listStats(client, patterns) + listStats(client, patterns, indexes) + + case "epoch", "e": + fmt.Printf("Getting epoch..\n") + + getEpoch(client) default: fmt.Printf("invalid command: %q\n", cmd) } } -func listStats(client adapter.StatsAPI, patterns []string) { - list, err := client.ListStats(patterns...) - if err != nil { - log.Fatalln("listing stats failed:", err) +func listStats(client adapter.StatsAPI, patterns []string, indexes []uint32) { + var err error + list := make([]adapter.StatIdentifier, 0) + if (len(patterns) == 0 && len(indexes) == 0) || len(patterns) != 0 { + list, err = client.ListStats(patterns...) + if err != nil { + log.Fatalln("listing stats failed:", err) + } + } + if len(indexes) != 0 { + dir, err := client.PrepareDirOnIndex(indexes...) + if err != nil { + log.Fatalln("listing stats failed:", err) + } + for _, onIndexSi := range dir.Entries { + list = append(list, onIndexSi.StatIdentifier) + } } - for _, stat := range list { - fmt.Printf(" - %v\n", stat) + fmt.Printf(" - %d\t %v\n", stat.Index, string(stat.Name)) } fmt.Printf("Listed %d stats\n", len(list)) } -func dumpStats(client adapter.StatsAPI, patterns []string, skipZeros bool) { - stats, err := client.DumpStats(patterns...) +func getEpoch(client adapter.StatsAPI) { + dir, err := client.PrepareDir() if err != nil { - log.Fatalln("dumping stats failed:", err) + log.Fatalln("failed to prepare dir in order to read epoch:", err) + } + d := *dir + fmt.Printf("Epoch %d\n", d.Epoch) +} + +func dumpStats(client adapter.StatsAPI, patterns []string, indexes []uint32, skipZeros bool) { + var err error + stats := make([]adapter.StatEntry, 0) + if (len(patterns) == 0 && len(indexes) == 0) || len(patterns) != 0 { + stats, err = client.DumpStats(patterns...) + if err != nil { + log.Fatalln("dumping stats failed:", err) + } + } + if len(indexes) != 0 { + dir, err := client.PrepareDirOnIndex(indexes...) + if err != nil { + log.Fatalln("dumping stats failed:", err) + } + for _, onIndexSi := range dir.Entries { + stats = append(stats, onIndexSi) + } } n := 0 |