Skip to content

Commit

Permalink
Populate content
Browse files Browse the repository at this point in the history
  • Loading branch information
rosstimothy committed Jan 23, 2025
1 parent f30df1d commit 46c9790
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 35 deletions.
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ require (
github.com/fsouza/fake-gcs-server v1.51.0
github.com/fxamacker/cbor/v2 v2.7.0
github.com/ghodss/yaml v1.0.0
github.com/gizak/termui/v3 v3.1.0
github.com/go-git/go-git/v5 v5.13.1
github.com/go-jose/go-jose/v3 v3.0.3
github.com/go-ldap/ldap/v3 v3.4.10
Expand Down Expand Up @@ -462,7 +461,6 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 // indirect
github.com/nsf/termbox-go v1.1.1 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/onsi/ginkgo/v2 v2.19.0 // indirect
Expand Down
11 changes: 4 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,8 @@ github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20241227172826-
github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20241227172826-c97b94eac159/go.mod h1:oO3inhSTqfeTU7JwquRhOEiV8E8hYcAM+lnE4kEv6xA=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
github.com/beevik/etree v1.4.1 h1:PmQJDDYahBGNKDcpdX8uPy1xRCwoCGVUiW669MEirVI=
github.com/beevik/etree v1.4.1/go.mod h1:gPNJNaBGVZ9AwsidazFZyygnd+0pAU38N4D+WemwKNs=
Expand Down Expand Up @@ -1038,6 +1040,8 @@ github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM=
github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b h1:MnAMdlwSltxJyULnrYbkZpp4k58Co7Tah3ciKhSNo0Q=
github.com/charmbracelet/x/exp/golden v0.0.0-20240815200342-61de596daa2b/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0 h1:qko3AQ4gK1MTS/de7F5hPGx6/k1u0w4TeYmBFwzYVP4=
github.com/charmbracelet/x/exp/strings v0.0.0-20240722160745-212f7b056ed0/go.mod h1:pBhA0ybfXv6hDjQUZ7hk1lVxBiUbupdw5R31yPUViVQ=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
Expand Down Expand Up @@ -1238,8 +1242,6 @@ github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uq
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc=
github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY=
github.com/go-asn1-ber/asn1-ber v1.5.7 h1:DTX+lbVTWaTw1hQ+PbZPlnDZPEIs0SS/GCZAl535dDk=
github.com/go-asn1-ber/asn1-ber v1.5.7/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
Expand Down Expand Up @@ -1836,7 +1838,6 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
Expand Down Expand Up @@ -1868,7 +1869,6 @@ github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa1
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
Expand Down Expand Up @@ -1921,9 +1921,6 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 h1:Up6+btDp321ZG5/zdSLo48H9Iaq0UQGthrhWC6pCxzE=
github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481/go.mod h1:yKZQO8QE2bHlgozqWDiRVqTFlLQSj30K/6SAK8EeYFw=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY=
github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
Expand Down
64 changes: 48 additions & 16 deletions tool/tctl/common/top/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/charmbracelet/lipgloss"
"github.com/dustin/go-humanize"
"github.com/gravitational/roundtrip"
"github.com/guptarohit/asciigraph"

"github.com/gravitational/teleport/api/constants"
)
Expand Down Expand Up @@ -183,11 +184,11 @@ func (m *topModel) contentView() string {
case 0:
return renderCommon(m.report, m.width)
case 1:
return renderBackend(m.report, m.width)
return renderBackend(m.report, m.height, m.width)
case 2:
return renderCache(m.report, m.width)
return renderCache(m.report, m.height, m.width)
case 3:
return renderWatcher(m.report, m.width)
return renderWatcher(m.report, m.height, m.width)
default:
return ""
}
Expand Down Expand Up @@ -310,10 +311,10 @@ func renderCommon(report *Report, width int) string {
)
}

func renderBackend(report *Report, width int) string {
func renderBackend(report *Report, height, width int) string {
latencyWidth := width / 3
requestsWidth := width * 2 / 3
topRequestsContent := boxedView("Top Backend Requests", "Test", requestsWidth)
topRequestsContent := boxedView("Top Backend Requests", requestsTableView(height, requestsWidth, report.Backend), requestsWidth)
readLatentcyContent := boxedView("Backend Read Percentiles", percentileTableView(latencyWidth, report.Backend.Read), latencyWidth)
batchReadLatentyContent := boxedView("Backend Batch Read Percentiles", percentileTableView(latencyWidth, report.Backend.BatchRead), latencyWidth)
writeLatencyContent := boxedView("Backend Write Percentiles", percentileTableView(latencyWidth, report.Backend.Write), latencyWidth)
Expand Down Expand Up @@ -342,11 +343,11 @@ func renderBackend(report *Report, width int) string {
)
}

func renderCache(report *Report, width int) string {
func renderCache(report *Report, height, width int) string {
latencyWidth := width / 3
requestsWidth := width * 2 / 3

topRequestsContent := boxedView("Top Cache Requests", "Test", requestsWidth)
topRequestsContent := boxedView("Top Cache Requests", requestsTableView(height, requestsWidth, report.Cache), requestsWidth)
readLatentcyContent := boxedView("Cache Read Percentiles", percentileTableView(latencyWidth, report.Cache.Read), latencyWidth)
batchReadLatentyContent := boxedView("Cache Batch Read Percentiles", percentileTableView(latencyWidth, report.Cache.BatchRead), latencyWidth)
writeLatencyContent := boxedView("Cache Write Percentiles", percentileTableView(latencyWidth, report.Cache.Write), latencyWidth)
Expand Down Expand Up @@ -375,22 +376,51 @@ func renderCache(report *Report, width int) string {
)
}

func renderWatcher(report *Report, width int) string {
columnWidth := width / 2
func renderWatcher(report *Report, height, width int) string {
graphWidth := width * 40 / 100
graphHeight := height / 3
eventsWidth := width * 60 / 100

topEventsContent := boxedView("Top Events Emitted", "Test", columnWidth)
eventCountContent := boxedView("Events/Sec", "123", columnWidth)
eventSizeContent := boxedView("Bytes/Sec", "12.4", columnWidth)
topEventsContent := boxedView("Top Events Emitted", eventsTableView(height, eventsWidth, report.Watcher), eventsWidth)

style := lipgloss.NewStyle().
Width(columnWidth).
dataCount := (graphWidth / 2)
eventData := report.Watcher.EventsPerSecond.Data(dataCount)
if len(eventData) < 1 {
eventData = []float64{0, 0}
}
countPlot := asciigraph.Plot(
eventData,
asciigraph.Height(graphHeight),
asciigraph.Width(graphWidth-15),
)
eventCountContent := boxedView("Events/Sec", countPlot, graphWidth)

sizeData := report.Watcher.BytesPerSecond.Data(dataCount)
if len(sizeData) < 1 {
sizeData = []float64{0, 0}
}
sizePlot := asciigraph.Plot(
sizeData,
asciigraph.Height(graphHeight),
asciigraph.Width(graphWidth-15),
)
eventSizeContent := boxedView("Bytes/Sec", sizePlot, graphWidth)

graphStyle := lipgloss.NewStyle().
Width(graphWidth).
Padding(0).
Margin(0).
Align(lipgloss.Left)

eventsStyle := lipgloss.NewStyle().
Width(eventsWidth).
Padding(0).
Margin(0).
Align(lipgloss.Left)

return lipgloss.JoinHorizontal(lipgloss.Left,
style.Render(topEventsContent),
style.Render(
eventsStyle.Render(topEventsContent),
graphStyle.Render(
lipgloss.JoinVertical(lipgloss.Left,
eventCountContent,
eventSizeContent,
Expand Down Expand Up @@ -469,6 +499,8 @@ var (

selectedColor = lipgloss.Color("4")

rangeColor = lipgloss.Color("24")

tableStyle = lipgloss.NewStyle().
BorderStyle(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("240"))
Expand Down
18 changes: 10 additions & 8 deletions tool/tctl/common/top/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ type Report struct {
// Go contains go runtime stats
Go GoStats
// Backend is a backend stats
Backend BackendStats
Backend *BackendStats
// Cache is cache stats
Cache BackendStats
Cache *BackendStats
// Cluster is cluster stats
Cluster ClusterStats
// Watcher is watcher stats
Expand Down Expand Up @@ -92,6 +92,7 @@ func (b *WatcherStats) SortedTopEvents() []Event {

return cmp.Compare(a.Resource, b.Resource)
})
slices.Reverse(out)
return out
}

Expand Down Expand Up @@ -177,6 +178,7 @@ func (b *BackendStats) SortedTopRequests() []Request {

return cmp.Compare(a.Key.Key, b.Key.Key)
})
slices.Reverse(out)
return out
}

Expand Down Expand Up @@ -341,10 +343,10 @@ func generateReport(metrics map[string]*dto.MetricFamily, prev *Report, period t
Version: types.V1,
Timestamp: time.Now().UTC(),
Hostname: hostname,
Backend: BackendStats{
Backend: &BackendStats{
TopRequests: make(map[RequestKey]Request),
},
Cache: BackendStats{
Cache: &BackendStats{
TopRequests: make(map[RequestKey]Request),
},
}
Expand All @@ -368,15 +370,15 @@ func generateReport(metrics map[string]*dto.MetricFamily, prev *Report, period t

var stats *BackendStats
if prev != nil {
stats = &prev.Backend
stats = prev.Backend
}
collectBackendStats(teleport.ComponentBackend, &re.Backend, stats)
collectBackendStats(teleport.ComponentBackend, re.Backend, stats)
if prev != nil {
stats = &prev.Cache
stats = prev.Cache
} else {
stats = nil
}
collectBackendStats(teleport.ComponentCache, &re.Cache, stats)
collectBackendStats(teleport.ComponentCache, re.Cache, stats)
re.Cache.QueueSize = getComponentGaugeValue(teleport.Component(teleport.ComponentAuth, teleport.ComponentCache),
metrics[teleport.MetricBackendWatcherQueues])

Expand Down
101 changes: 99 additions & 2 deletions tool/tctl/common/top/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ func tableView(width int, first, second column) string {
rows = append(rows, lipgloss.JoinHorizontal(lipgloss.Left,
leftColumn.Render(first.content[i]),
rightColumn.Render(second.content[i]),
),
)
))
}

return style.Render(lipgloss.JoinVertical(lipgloss.Left, rows...))
Expand Down Expand Up @@ -78,3 +77,101 @@ func percentileTableView(width int, hist Histogram) string {

return tableView(width, firstColumn, secondColumn)
}

func requestsTableView(height, width int, stats *BackendStats) string {
style := lipgloss.NewStyle().
Width(width).
MaxHeight(height - 10)

countColumn := lipgloss.NewStyle().
Width(10).
Border(lipgloss.RoundedBorder(), false, false, false, false).
Align(lipgloss.Left)

frequencyColumn := lipgloss.NewStyle().
Width(8).
Border(lipgloss.RoundedBorder(), false, false, false, true).
Align(lipgloss.Left)

keyColumn := lipgloss.NewStyle().
Width(width-18).
Border(lipgloss.RoundedBorder(), false, false, false, true).
Align(lipgloss.Left)

rangeKeyColumn := lipgloss.NewStyle().
Width(width-18).
Border(lipgloss.RoundedBorder(), false, false, false, true).
Align(lipgloss.Left).
Bold(true)

rows := []string{
lipgloss.JoinHorizontal(lipgloss.Left,
countColumn.Render("Count"),
frequencyColumn.Render("Req/Sec"),
frequencyColumn.Render("Key"),
),
}

for _, req := range stats.SortedTopRequests() {
var key string
if req.Key.Range {
key = rangeKeyColumn.Render(req.Key.Key)
} else {
key = keyColumn.Render(req.Key.Key)
}

rows = append(rows, lipgloss.JoinHorizontal(lipgloss.Left,
countColumn.Render(humanize.FormatFloat("", float64(req.Count))),
frequencyColumn.Render(humanize.FormatFloat("", req.GetFreq())),
key,
))
}

return style.Render(lipgloss.JoinVertical(lipgloss.Left, rows...))
}

func eventsTableView(height, width int, stats *WatcherStats) string {
style := lipgloss.NewStyle().
Width(width).
MaxHeight(height - 10)

countColumn := lipgloss.NewStyle().
Width(10).
Border(lipgloss.RoundedBorder(), false, false, false, false).
Align(lipgloss.Left)

frequencyColumn := lipgloss.NewStyle().
Width(8).
Border(lipgloss.RoundedBorder(), false, false, false, true).
Align(lipgloss.Left)

sizeColumn := lipgloss.NewStyle().
Width(8).
Border(lipgloss.RoundedBorder(), false, false, false, true).
Align(lipgloss.Left)

resourceColumn := lipgloss.NewStyle().
Width(width-18).
Border(lipgloss.RoundedBorder(), false, false, false, true).
Align(lipgloss.Left)

rows := []string{
lipgloss.JoinHorizontal(lipgloss.Left,
countColumn.Render("Count"),
frequencyColumn.Render("Req/Sec"),
frequencyColumn.Render("Avg Size"),
frequencyColumn.Render("Resource"),
),
}

for _, event := range stats.SortedTopEvents() {
rows = append(rows, lipgloss.JoinHorizontal(lipgloss.Left,
countColumn.Render(humanize.FormatFloat("", float64(event.Count))),
frequencyColumn.Render(humanize.FormatFloat("", event.GetFreq())),
sizeColumn.Render(humanize.FormatFloat("", event.AverageSize())),
resourceColumn.Render(event.Resource),
))
}

return style.Render(lipgloss.JoinVertical(lipgloss.Left, rows...))
}

0 comments on commit 46c9790

Please sign in to comment.