From 5dc53f05cdc6e6348b08d0d0f3f6bf3ae0cd3701 Mon Sep 17 00:00:00 2001 From: Tim Ross Date: Thu, 23 Jan 2025 18:13:32 -0500 Subject: [PATCH] add comments --- tool/tctl/common/top/box.go | 23 +++++++++++++++++++++++ tool/tctl/common/top/model.go | 22 ++++++++++++++++++++++ tool/tctl/common/top/report.go | 2 ++ tool/tctl/common/top/table.go | 9 +++++++++ 4 files changed, 56 insertions(+) diff --git a/tool/tctl/common/top/box.go b/tool/tctl/common/top/box.go index 9b166e74a184b..674baafd9e85f 100644 --- a/tool/tctl/common/top/box.go +++ b/tool/tctl/common/top/box.go @@ -22,6 +22,29 @@ import ( "github.com/charmbracelet/lipgloss" ) +// Top: "─", +// Bottom: "─", +// Left: "│", +// Right: "│", +// TopLeft: "╭", +// TopRight: "╮", +// BottomLeft: "╰", +// BottomRight: "╯", +// MiddleLeft: "├", +// MiddleRight: "┤", +// Middle: "┼", +// MiddleTop: "┬", +// MiddleBottom: "┴", + +// boxedView wraps the provided content in a rounded border, +// with the title embedded in the top. For example, if the +// content was \t\t\tHello and the title was Some Heading the +// returned content would be: +// +// ╭Some Heading────────╮ +// │ │ +// │ Hello │ +// ╰────────────────────╯ func boxedView(title string, content string, width int) string { rounderBorder := lipgloss.RoundedBorder() diff --git a/tool/tctl/common/top/model.go b/tool/tctl/common/top/model.go index ede658350315d..5d7832f60ef9a 100644 --- a/tool/tctl/common/top/model.go +++ b/tool/tctl/common/top/model.go @@ -34,6 +34,9 @@ import ( "github.com/gravitational/teleport/api/constants" ) +// topModel is a [tea.Model] implementation which +// displays various tabs and content displayed by +// the tctl top command. type topModel struct { width int height int @@ -52,6 +55,9 @@ func newTopModel(refreshInterval time.Duration, clt *roundtrip.Client) *topModel } } +// refresh pulls metrics from Teleport and builds +// a [Report] according to the configured refresh +// interval. func (m *topModel) refresh() tea.Cmd { return func() tea.Msg { if m.report != nil { @@ -75,6 +81,8 @@ func (m *topModel) Init() tea.Cmd { return m.refresh() } +// Update processes messages in order to updated the +// view based on user input and new metrics data. func (m *topModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { switch msg := msg.(type) { case tea.WindowSizeMsg: @@ -105,6 +113,8 @@ func (m *topModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, nil } +// View formats the metrics and draws them to +// the screen. func (m *topModel) View() string { availableHeight := m.height header := headerView(m.selected, m.width) @@ -125,6 +135,9 @@ func (m *topModel) View() string { ) } +// headerView generates the tab bar displayed at +// the top of the screen. The selectedTab will be +// rendered a different color to indicate as such. func headerView(selectedTab int, width int) string { tabs := tabView(selectedTab) @@ -138,6 +151,8 @@ func headerView(selectedTab int, width int) string { return tabs + lipgloss.NewStyle().Render(filler) + "\n" + strings.Repeat("‾", width) } +// footerView generates the help text displayed at the +// bottom of the screen. func (m *topModel) footerView() string { underscore := lipgloss.NewStyle().Underline(true).Render(" ") underline := strings.Repeat(underscore, m.width) @@ -173,6 +188,8 @@ func (m *topModel) footerView() string { statusBarStyle.Render(right) } +// contentView generates the appropriate content +// based on which tab is selected. func (m *topModel) contentView() string { if m.report == nil { return "" @@ -192,6 +209,7 @@ func (m *topModel) contentView() string { } } +// renderCommon generates the view for the cluster stats tab. func renderCommon(report *Report, width int) string { columnWidth := width / 2 @@ -294,6 +312,7 @@ func renderCommon(report *Report, width int) string { ) } +// renderBackend generates the view for the backend stats tab. func renderBackend(report *Report, height, width int) string { latencyWidth := width / 3 requestsWidth := width * 2 / 3 @@ -326,6 +345,7 @@ func renderBackend(report *Report, height, width int) string { ) } +// renderCache generates the view for the cache stats tab. func renderCache(report *Report, height, width int) string { latencyWidth := width / 3 requestsWidth := width * 2 / 3 @@ -359,6 +379,7 @@ func renderCache(report *Report, height, width int) string { ) } +// renderWatcher generates the view for the watcher stats tab. func renderWatcher(report *Report, height, width int) string { graphWidth := width * 40 / 100 graphHeight := height / 3 @@ -412,6 +433,7 @@ func renderWatcher(report *Report, height, width int) string { ) } +// tabView renders the tabbed content in the header. func tabView(selectedTab int) string { output := lipgloss.NewStyle(). Underline(true). diff --git a/tool/tctl/common/top/report.go b/tool/tctl/common/top/report.go index f6d8c5f228a37..b4ba2ce72bace 100644 --- a/tool/tctl/common/top/report.go +++ b/tool/tctl/common/top/report.go @@ -289,6 +289,8 @@ type Percentile struct { Value time.Duration } +// Percentiles returns an iterator of the percentiles +// of the buckets within the historgram. func (h Histogram) Percentiles() iter.Seq[Percentile] { return func(yield func(Percentile) bool) { if h.Count == 0 { diff --git a/tool/tctl/common/top/table.go b/tool/tctl/common/top/table.go index 4d263e8b69e98..8d8ae9024444c 100644 --- a/tool/tctl/common/top/table.go +++ b/tool/tctl/common/top/table.go @@ -27,6 +27,9 @@ type column struct { content []string } +// tableView renders two columns in a table like view +// that has no headings. Content lenghts of the columns +// is required to match. func tableView(width int, first, second column) string { if len(first.content) != len(second.content) { panic("column content must have equal heights") @@ -55,6 +58,8 @@ func tableView(width int, first, second column) string { return style.Render(lipgloss.JoinVertical(lipgloss.Left, rows...)) } +// percentileTableView renders a dynamic table like view +// displaying the percentiles of the provided histogram. func percentileTableView(width int, hist Histogram) string { firstColumn := column{ width: width / 2, @@ -78,6 +83,8 @@ func percentileTableView(width int, hist Histogram) string { return tableView(width, firstColumn, secondColumn) } +// requestsTableView renders a table like view +// displaying information about backend request stats. func requestsTableView(height, width int, stats *BackendStats) string { style := lipgloss.NewStyle(). Width(width). @@ -123,6 +130,8 @@ func requestsTableView(height, width int, stats *BackendStats) string { return style.Render(lipgloss.JoinVertical(lipgloss.Left, rows...)) } +// eventsTableView renders a table like view +// displaying information about watcher event stats. func eventsTableView(height, width int, stats *WatcherStats) string { style := lipgloss.NewStyle(). Width(width).