You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.3 KiB

Improved tm-monitor formatting (#4023) * tm-monitor: tweaked formatting of start time and avg tx throughput. * tm-monitor: update health when validator number is updated. * Updated CHANGELOG_PENDING * Added PR number to CHANGELOG_PENDING. Improves `tm-monitor` formatting of start time (RFC1123 without unnecessary precision) and avg tx throughput (three decimal places). The old tx throughput display was confusing during local testing where the tx rate is low and displayed as 0. Also updates the monitor health whenever the validator number changes. It otherwise starts with moderate health and fails to update this once it discovers the validators, leading to incorrect health reporting and invalid uptime statistics. Let me know if you would like me to submit this as a separate PR. ### Before: ``` 2019-09-29 20:40:00.992834 +0200 CEST m=+0.024057059 up -92030989600.42% Height: 2518 Avg block time: 1275.496 ms Avg tx throughput: 0 per sec Avg block latency: 2.464 ms Active nodes: 4/4 (health: moderate) Validators: 4 NAME HEIGHT BLOCK LATENCY ONLINE VALIDATOR localhost:26657 2518 0.935 ms true true localhost:26660 2518 0.710 ms true true localhost:26662 2518 0.708 ms true true localhost:26664 2518 0.717 ms true true ``` ### After: ``` Sun, 29 Sep 2019 20:21:59 +0200 up 100.00% Height: 2480 Avg block time: 1361.445 ms Avg tx throughput: 0.735 per sec Avg block latency: 4.232 ms Active nodes: 4/4 (health: full) Validators: 4 NAME HEIGHT BLOCK LATENCY ONLINE VALIDATOR localhost:26657 2480 1.174 ms true true localhost:26660 2480 1.037 ms true true localhost:26662 2480 0.981 ms true true localhost:26664 2480 0.995 ms true true ```
5 years ago
Improved tm-monitor formatting (#4023) * tm-monitor: tweaked formatting of start time and avg tx throughput. * tm-monitor: update health when validator number is updated. * Updated CHANGELOG_PENDING * Added PR number to CHANGELOG_PENDING. Improves `tm-monitor` formatting of start time (RFC1123 without unnecessary precision) and avg tx throughput (three decimal places). The old tx throughput display was confusing during local testing where the tx rate is low and displayed as 0. Also updates the monitor health whenever the validator number changes. It otherwise starts with moderate health and fails to update this once it discovers the validators, leading to incorrect health reporting and invalid uptime statistics. Let me know if you would like me to submit this as a separate PR. ### Before: ``` 2019-09-29 20:40:00.992834 +0200 CEST m=+0.024057059 up -92030989600.42% Height: 2518 Avg block time: 1275.496 ms Avg tx throughput: 0 per sec Avg block latency: 2.464 ms Active nodes: 4/4 (health: moderate) Validators: 4 NAME HEIGHT BLOCK LATENCY ONLINE VALIDATOR localhost:26657 2518 0.935 ms true true localhost:26660 2518 0.710 ms true true localhost:26662 2518 0.708 ms true true localhost:26664 2518 0.717 ms true true ``` ### After: ``` Sun, 29 Sep 2019 20:21:59 +0200 up 100.00% Height: 2480 Avg block time: 1361.445 ms Avg tx throughput: 0.735 per sec Avg block latency: 4.232 ms Active nodes: 4/4 (health: full) Validators: 4 NAME HEIGHT BLOCK LATENCY ONLINE VALIDATOR localhost:26657 2480 1.174 ms true true localhost:26660 2480 1.037 ms true true localhost:26662 2480 0.981 ms true true localhost:26664 2480 0.995 ms true true ```
5 years ago
  1. package main
  2. import (
  3. "fmt"
  4. "io"
  5. "os"
  6. "text/tabwriter"
  7. "time"
  8. monitor "github.com/tendermint/tendermint/tools/tm-monitor/monitor"
  9. )
  10. const (
  11. // Default refresh rate - 200ms
  12. defaultRefreshRate = time.Millisecond * 200
  13. )
  14. // Ton - table of nodes.
  15. //
  16. // It produces the unordered list of nodes and updates it periodically.
  17. //
  18. // Default output is stdout, but it could be changed. Note if you want for
  19. // refresh to work properly, output must support [ANSI escape
  20. // codes](http://en.wikipedia.org/wiki/ANSI_escape_code).
  21. //
  22. // Ton was inspired by [Linux top
  23. // program](https://en.wikipedia.org/wiki/Top_(software)) as the name suggests.
  24. type Ton struct {
  25. monitor *monitor.Monitor
  26. RefreshRate time.Duration
  27. Output io.Writer
  28. quit chan struct{}
  29. }
  30. func NewTon(m *monitor.Monitor) *Ton {
  31. return &Ton{
  32. RefreshRate: defaultRefreshRate,
  33. Output: os.Stdout,
  34. quit: make(chan struct{}),
  35. monitor: m,
  36. }
  37. }
  38. func (o *Ton) Start() {
  39. clearScreen(o.Output)
  40. o.Print()
  41. go o.refresher()
  42. }
  43. func (o *Ton) Print() {
  44. moveCursor(o.Output, 1, 1)
  45. o.printHeader()
  46. fmt.Println()
  47. o.printTable()
  48. }
  49. func (o *Ton) Stop() {
  50. close(o.quit)
  51. }
  52. func (o *Ton) printHeader() {
  53. n := o.monitor.Network
  54. fmt.Fprintf(o.Output, "%v up %.2f%%\n", n.StartTime().Format(time.RFC1123Z), n.Uptime())
  55. fmt.Println()
  56. fmt.Fprintf(o.Output, "Height: %d\n", n.Height)
  57. fmt.Fprintf(o.Output, "Avg block time: %.3f ms\n", n.AvgBlockTime)
  58. fmt.Fprintf(o.Output, "Avg tx throughput: %.3f per sec\n", n.AvgTxThroughput)
  59. fmt.Fprintf(o.Output, "Avg block latency: %.3f ms\n", n.AvgBlockLatency)
  60. fmt.Fprintf(o.Output,
  61. "Active nodes: %d/%d (health: %s) Validators: %d\n",
  62. n.NumNodesMonitoredOnline,
  63. n.NumNodesMonitored,
  64. n.GetHealthString(),
  65. n.NumValidators)
  66. }
  67. func (o *Ton) printTable() {
  68. w := tabwriter.NewWriter(o.Output, 0, 0, 5, ' ', 0)
  69. fmt.Fprintln(w, "NAME\tHEIGHT\tBLOCK LATENCY\tONLINE\tVALIDATOR\t")
  70. for _, n := range o.monitor.Nodes {
  71. fmt.Fprintln(w, fmt.Sprintf("%s\t%d\t%.3f ms\t%v\t%v\t", n.Name, n.Height, n.BlockLatency, n.Online, n.IsValidator))
  72. }
  73. w.Flush()
  74. }
  75. // Internal loop for refreshing
  76. func (o *Ton) refresher() {
  77. for {
  78. select {
  79. case <-o.quit:
  80. return
  81. case <-time.After(o.RefreshRate):
  82. o.Print()
  83. }
  84. }
  85. }
  86. func clearScreen(w io.Writer) {
  87. fmt.Fprint(w, "\033[2J")
  88. }
  89. func moveCursor(w io.Writer, x int, y int) {
  90. fmt.Fprintf(w, "\033[%d;%dH", x, y)
  91. }