mirror of
https://github.com/gravitational/teleport
synced 2024-10-18 16:24:03 +00:00
tctl: fix tctl top
colors on dark terminals
If we leave `TextStyle` empty on UI elements, it will use the default foreground color defined by the terminal (light for dark terminals and vice versa). Same goes for `BorderStyle`. A few other tweaks to UI and source metrics: - update table ratios to prevent hiding output rows on short (height) terminal windows - update tab selector style to use bold/underline instead of colors to mark selected tab - print `No data` in histogram tables when there are no values - don't report the local cluster in `remote_clusters` metric
This commit is contained in:
parent
1d63421c48
commit
96375c7d3d
|
@ -159,13 +159,13 @@ var (
|
|||
generateRequestsCurrent = prometheus.NewGauge(
|
||||
prometheus.GaugeOpts{
|
||||
Name: teleport.MetricGenerateRequestsCurrent,
|
||||
Help: "Number of current generate requests",
|
||||
Help: "Number of current generate requests for server keys",
|
||||
},
|
||||
)
|
||||
generateRequestsLatencies = prometheus.NewHistogram(
|
||||
prometheus.HistogramOpts{
|
||||
Name: teleport.MetricGenerateRequestsHistogram,
|
||||
Help: "Latency for generate requests",
|
||||
Help: "Latency for generate requests for server keys",
|
||||
// lowest bucket start of upper bound 0.001 sec (1 ms) with factor 2
|
||||
// highest bucket start of 0.001 sec * 2^15 == 32.768 sec
|
||||
Buckets: prometheus.ExponentialBuckets(0.001, 2, 16),
|
||||
|
|
|
@ -44,14 +44,14 @@ import (
|
|||
var (
|
||||
remoteClustersStats = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "remote_clusters",
|
||||
Name: teleport.MetricRemoteClusters,
|
||||
Help: "Number inbound connections from remote clusters and clusters stats",
|
||||
},
|
||||
[]string{"cluster"},
|
||||
)
|
||||
trustedClustersStats = prometheus.NewGaugeVec(
|
||||
prometheus.GaugeOpts{
|
||||
Name: "trusted_clusters",
|
||||
Name: teleport.MetricTrustedClusters,
|
||||
Help: "Number of tunnels per state",
|
||||
},
|
||||
[]string{"cluster", "state"},
|
||||
|
@ -400,13 +400,12 @@ func (s *server) fetchClusterPeers() error {
|
|||
}
|
||||
|
||||
func (s *server) reportClusterStats() error {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
s.Warningf("Recovered from panic: %v.", r)
|
||||
}
|
||||
}()
|
||||
clusters := s.GetSites()
|
||||
for _, cluster := range clusters {
|
||||
if _, ok := cluster.(*localSite); ok {
|
||||
// Don't count local cluster tunnels.
|
||||
continue
|
||||
}
|
||||
gauge, err := remoteClustersStats.GetMetricWithLabelValues(cluster.GetName())
|
||||
if err != nil {
|
||||
return trace.Wrap(err)
|
||||
|
|
|
@ -37,6 +37,9 @@ const (
|
|||
// MetricRemoteClusters measures connected remote clusters
|
||||
MetricRemoteClusters = "remote_clusters"
|
||||
|
||||
// MetricTrustedClusters counts trusted clusters
|
||||
MetricTrustedClusters = "trusted_clusters"
|
||||
|
||||
// TagCluster is a metric tag for a cluster
|
||||
TagCluster = "cluster"
|
||||
)
|
||||
|
|
|
@ -134,16 +134,13 @@ func (c *TopCommand) Top(client *roundtrip.Client) error {
|
|||
|
||||
func (c *TopCommand) render(ctx context.Context, re Report, eventID string) error {
|
||||
h := widgets.NewParagraph()
|
||||
h.Text = ""
|
||||
h.Text = fmt.Sprintf("Report Generated at %v for host %v. Press <q> or Ctrl-C to quit.",
|
||||
re.Timestamp.Format(teleport.HumanDateFormatSeconds), re.Hostname)
|
||||
h.BorderStyle = ui.NewStyle(ui.ColorBlack)
|
||||
h.Border = false
|
||||
h.TextStyle = ui.NewStyle(ui.ColorMagenta)
|
||||
|
||||
backendRequestsTable := func(title string, b BackendStats) *widgets.Table {
|
||||
t := widgets.NewTable()
|
||||
t.BorderStyle = ui.NewStyle(ui.ColorBlack)
|
||||
t.Title = title
|
||||
t.TitleStyle = ui.NewStyle(ui.ColorCyan)
|
||||
t.ColumnWidths = []int{10, 10, 10, 50000}
|
||||
|
@ -160,17 +157,14 @@ func (c *TopCommand) render(ctx context.Context, re Report, eventID string) erro
|
|||
req.Key.Key,
|
||||
})
|
||||
}
|
||||
t.TextStyle = ui.NewStyle(ui.ColorBlack)
|
||||
return t
|
||||
}
|
||||
|
||||
t1 := widgets.NewTable()
|
||||
t1.Title = "Cluster Stats"
|
||||
t1.TitleStyle = ui.NewStyle(ui.ColorCyan)
|
||||
t1.BorderStyle = ui.NewStyle(ui.ColorBlack)
|
||||
t1.ColumnWidths = []int{30, 50000}
|
||||
t1.RowSeparator = false
|
||||
t1.TextStyle = ui.NewStyle(ui.ColorBlack)
|
||||
t1.Rows = [][]string{
|
||||
[]string{"Interactive Sessions", humanize.FormatFloat("", re.Cluster.InteractiveSessions)},
|
||||
[]string{"Cert Gen Active Requests", humanize.FormatFloat("", re.Cluster.GenerateRequests)},
|
||||
|
@ -187,10 +181,8 @@ func (c *TopCommand) render(ctx context.Context, re Report, eventID string) erro
|
|||
t2 := widgets.NewTable()
|
||||
t2.Title = "Process Stats"
|
||||
t2.TitleStyle = ui.NewStyle(ui.ColorCyan)
|
||||
t2.BorderStyle = ui.NewStyle(ui.ColorBlack)
|
||||
t2.ColumnWidths = []int{30, 50000}
|
||||
t2.RowSeparator = false
|
||||
t2.TextStyle = ui.NewStyle(ui.ColorBlack)
|
||||
t2.Rows = [][]string{
|
||||
[]string{"Start Time", re.Process.StartTime.Format(teleport.HumanDateFormatSeconds)},
|
||||
[]string{"Resident Memory Bytes", humanize.Bytes(uint64(re.Process.ResidentMemoryBytes))},
|
||||
|
@ -202,10 +194,8 @@ func (c *TopCommand) render(ctx context.Context, re Report, eventID string) erro
|
|||
t3 := widgets.NewTable()
|
||||
t3.Title = "Go Runtime Stats"
|
||||
t3.TitleStyle = ui.NewStyle(ui.ColorCyan)
|
||||
t3.BorderStyle = ui.NewStyle(ui.ColorBlack)
|
||||
t3.ColumnWidths = []int{30, 50000}
|
||||
t3.RowSeparator = false
|
||||
t3.TextStyle = ui.NewStyle(ui.ColorBlack)
|
||||
t3.Rows = [][]string{
|
||||
[]string{"Allocated Memory", humanize.Bytes(uint64(re.Go.AllocBytes))},
|
||||
[]string{"Goroutines", humanize.FormatFloat("", re.Go.Goroutines)},
|
||||
|
@ -219,10 +209,16 @@ func (c *TopCommand) render(ctx context.Context, re Report, eventID string) erro
|
|||
t := widgets.NewTable()
|
||||
t.Title = title
|
||||
t.TitleStyle = ui.NewStyle(ui.ColorCyan)
|
||||
t.BorderStyle = ui.NewStyle(ui.ColorBlack)
|
||||
|
||||
if hist.Count == 0 {
|
||||
t.Rows = [][]string{
|
||||
[]string{"No data"},
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
t.ColumnWidths = []int{30, 50000}
|
||||
t.RowSeparator = false
|
||||
t.TextStyle = ui.NewStyle(ui.ColorBlack)
|
||||
t.Rows = [][]string{
|
||||
[]string{"Percentile", "Latency"},
|
||||
}
|
||||
|
@ -240,8 +236,8 @@ func (c *TopCommand) render(ctx context.Context, re Report, eventID string) erro
|
|||
grid.SetRect(0, 0, termWidth, termHeight)
|
||||
|
||||
tabpane := widgets.NewTabPane("[1] Common", "[2] Backend Stats", "[3] Cache Stats")
|
||||
tabpane.ActiveTabStyle = ui.NewStyle(ui.ColorCyan)
|
||||
tabpane.InactiveTabStyle = ui.NewStyle(ui.ColorBlack)
|
||||
tabpane.ActiveTabStyle = ui.NewStyle(ui.ColorCyan, ui.ColorClear, ui.ModifierBold|ui.ModifierUnderline)
|
||||
tabpane.InactiveTabStyle = ui.NewStyle(ui.ColorCyan)
|
||||
tabpane.Border = false
|
||||
|
||||
switch eventID {
|
||||
|
@ -254,12 +250,12 @@ func (c *TopCommand) render(ctx context.Context, re Report, eventID string) erro
|
|||
),
|
||||
ui.NewRow(0.95,
|
||||
ui.NewCol(0.5,
|
||||
ui.NewRow(0.15, t1),
|
||||
ui.NewRow(0.15, t2),
|
||||
ui.NewRow(0.15, t3),
|
||||
ui.NewRow(0.3, t1),
|
||||
ui.NewRow(0.3, t2),
|
||||
ui.NewRow(0.3, t3),
|
||||
),
|
||||
ui.NewCol(0.5,
|
||||
ui.NewRow(0.3, percentileTable("Generate Certificates Histogram", re.Cluster.GenerateRequestsHistogram)),
|
||||
ui.NewRow(0.3, percentileTable("Generate Server Certificates Histogram", re.Cluster.GenerateRequestsHistogram)),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue