From 119ec1fdfc52657d32ec803cfc98a49403242e98 Mon Sep 17 00:00:00 2001 From: Dmytro Vovk Date: Fri, 9 Aug 2024 16:38:46 +0100 Subject: [PATCH] diagnostics: refactored cpu info (#11544) Refactored printing cpu info: - move CPU details to table - move CPU usage next to details table - refactor code --- cmd/diag/sysinfo/sysinfo.go | 130 ++++++++++++------------------------ cmd/diag/util/util.go | 2 +- 2 files changed, 44 insertions(+), 88 deletions(-) diff --git a/cmd/diag/sysinfo/sysinfo.go b/cmd/diag/sysinfo/sysinfo.go index d3a8eff804f..dd47052499c 100644 --- a/cmd/diag/sysinfo/sysinfo.go +++ b/cmd/diag/sysinfo/sysinfo.go @@ -19,7 +19,6 @@ package sysinfo import ( "fmt" "sort" - "strconv" "strings" "github.com/jedib0t/go-pretty/v6/table" @@ -76,20 +75,16 @@ func collectInfo(cliCtx *cli.Context) error { util.RenderError(err) } - var builder strings.Builder - builder.WriteString("Disk info:\n") - builder.WriteString(data.Disk.Details) - builder.WriteString("\n\n") - builder.WriteString("CPU info:\n") - writeCPUToStringBuilder(data.CPU, &builder) - - processes := sysutils.GetProcessesInfo() cpuusage := sysutils.CPUUsage() + processes := sysutils.GetProcessesInfo() totalMemory := sysutils.TotalMemoryUsage() - builder.WriteString("\n\nProcesses info:\n") + + var builder strings.Builder + + writeDiskInfoToStringBuilder(data.Disk, &builder) + writeCPUInfoToStringBuilder(data.CPU, cpuusage, &builder) + writeProcessesToStringBuilder(processes, cpuusage.Total, totalMemory, &builder) - builder.WriteString("\n\nCPU usage details:\n") - writeCPUUsageToStringBuilder(cpuusage.Cores, &builder) // Save data to file err = util.SaveDataToFile(cliCtx.String(ExportPathFlag.Name), cliCtx.String(ExportFileNameFlag.Name), builder.String()) @@ -100,27 +95,45 @@ func collectInfo(cliCtx *cli.Context) error { return nil } -func writeCPUToStringBuilder(cpuInfo []diagnostics.CPUInfo, builder *strings.Builder) { - spacing := calculateSpacing([]string{"CPU", "VendorID", "Family", "Model", "Stepping", "PhysicalID", "CoreID", "Cores", "ModelName", "Mhz", "CacheSize", "Flags", "Microcode"}) +func writeDiskInfoToStringBuilder(diskInfo diagnostics.DiskInfo, builder *strings.Builder) { + builder.WriteString("Disk info:\n") + builder.WriteString(diskInfo.Details) + builder.WriteString("\n\n") +} + +func writeCPUInfoToStringBuilder(cpuInfo []diagnostics.CPUInfo, cpuusage sysutils.CPUUsageInfo, builder *strings.Builder) { + writeOweralCPUInfoToStringBuilder(cpuInfo, builder) + writeCPUUsageToStringBuilder(cpuusage.Cores, builder) +} +func writeOweralCPUInfoToStringBuilder(cpuInfo []diagnostics.CPUInfo, builder *strings.Builder) { + builder.WriteString("CPU info:\n") + header := table.Row{"CPU", "VendorID", "Family", "Model", "Stepping", "PhysicalID", "CoreID", "Cores", "ModelName", "Mhz", "CacheSize", "Flags", "Microcode"} + rows := make([]table.Row, 0, len(cpuInfo)) for _, cpu := range cpuInfo { - writeStringToBuilder(builder, "CPU", strconv.Itoa(int(cpu.CPU)), spacing) - writeStringToBuilder(builder, "VendorID", cpu.VendorID, spacing) - writeStringToBuilder(builder, "Family", cpu.Family, spacing) - writeStringToBuilder(builder, "Model", cpu.Model, spacing) - writeStringToBuilder(builder, "Stepping", strconv.Itoa(int(cpu.Stepping)), spacing) - writeStringToBuilder(builder, "PhysicalID", cpu.PhysicalID, spacing) - writeStringToBuilder(builder, "CoreID", cpu.CoreID, spacing) - writeStringToBuilder(builder, "Cores", strconv.Itoa(int(cpu.Cores)), spacing) - writeStringToBuilder(builder, "ModelName", cpu.ModelName, spacing) - writeStringToBuilder(builder, "Mhz", fmt.Sprintf("%g", cpu.Mhz), spacing) - writeStringToBuilder(builder, "CacheSize", strconv.Itoa(int(cpu.CacheSize)), spacing) - writeStringToBuilder(builder, "Flags", strings.Join(cpu.Flags, ", "), spacing) - writeStringToBuilder(builder, "Microcode", cpu.Microcode, spacing) + rows = append(rows, table.Row{cpu.CPU, cpu.VendorID, cpu.Family, cpu.Model, cpu.Stepping, cpu.PhysicalID, cpu.CoreID, cpu.Cores, cpu.ModelName, cpu.Mhz, cpu.CacheSize, strings.Join(cpu.Flags, ", "), cpu.Microcode}) + } + + cpuDataTable := util.ExportTable(header, rows, nil) + builder.WriteString(cpuDataTable) + builder.WriteString("\n\n") +} + +func writeCPUUsageToStringBuilder(cpuUsage []float64, builder *strings.Builder) { + builder.WriteString("CPU usage:\n") + header := table.Row{"Core #", "% CPU"} + rows := make([]table.Row, 0, len(cpuUsage)) + for idx, core := range cpuUsage { + rows = append(rows, table.Row{idx + 1, fmt.Sprintf("%.2f", core)}) } + + cpuUsageDataTable := util.ExportTable(header, rows, nil) + builder.WriteString(cpuUsageDataTable) } func writeProcessesToStringBuilder(prcInfo []*sysutils.ProcessInfo, cpuUsage float64, totalMemory float64, builder *strings.Builder) { + builder.WriteString("\n\nProcesses info:\n") + prcInfo = sortProcessesByCPU(prcInfo) rows := make([]table.Row, 0) header := table.Row{"PID", "Name", "% CPU", "% Memory"} @@ -131,38 +144,10 @@ func writeProcessesToStringBuilder(prcInfo []*sysutils.ProcessInfo, cpuUsage flo rows = append(rows, table.Row{process.Pid, process.Name, cpu, memory}) } - t := table.NewWriter() - - t.AppendHeader(header) - if len(rows) > 0 { - t.AppendRows(rows) - } - t.AppendSeparator() - t.AppendRow(table.Row{"Totals", "", fmt.Sprintf("%.2f", cpuUsage), fmt.Sprintf("%.2f", totalMemory)}) - t.AppendSeparator() - - result := t.Render() - builder.WriteString(result) -} - -func writeCPUUsageToStringBuilder(cpuUsage []float64, builder *strings.Builder) { - rows := make([]table.Row, 0) - header := table.Row{"Core #", "% CPU"} - - for idx, core := range cpuUsage { - rows = append(rows, table.Row{idx + 1, fmt.Sprintf("%.2f", core)}) - } - - t := table.NewWriter() - - t.AppendHeader(header) - if len(rows) > 0 { - t.AppendRows(rows) - } + footer := table.Row{"Totals", "", fmt.Sprintf("%.2f", cpuUsage), fmt.Sprintf("%.2f", totalMemory)} - t.AppendSeparator() - result := t.Render() - builder.WriteString(result) + processesTable := util.ExportTable(header, rows, footer) + builder.WriteString(processesTable) } func sortProcesses(prcInfo []*sysutils.ProcessInfo, sorting SortType) []*sysutils.ProcessInfo { @@ -193,35 +178,6 @@ func sortProcessesByPID(prcInfo []*sysutils.ProcessInfo) []*sysutils.ProcessInfo return sortProcesses(prcInfo, SortByPID) } -func calculateSpacing(keysArray []string) int { - max := 0 - for _, key := range keysArray { - if len(key) > max { - max = len(key) - } - } - - return max + 3 -} - -func writeStringToBuilder(result *strings.Builder, name string, value string, spacing int) { - marging := 3 - if value == "" { - value = "N/A" - } - - writeSpacesToBuilder(result, marging) - result.WriteString(name) - result.WriteString(":") - writeSpacesToBuilder(result, spacing-len(name)-1) - result.WriteString(value) - result.WriteString("\n") -} - -func writeSpacesToBuilder(result *strings.Builder, spaces int) { - result.WriteString(strings.Repeat(" ", spaces)) -} - func getData(cliCtx *cli.Context) (diagnostics.HardwareInfo, error) { var data diagnostics.HardwareInfo url := "http://" + cliCtx.String(flags.DebugURLFlag.Name) + flags.ApiPath + "/hardware-info" diff --git a/cmd/diag/util/util.go b/cmd/diag/util/util.go index 26e8ed63542..305ad1426c7 100644 --- a/cmd/diag/util/util.go +++ b/cmd/diag/util/util.go @@ -76,7 +76,7 @@ func RenderJson(data interface{}) { } } -func ExportTable(title string, header table.Row, rows []table.Row, footer table.Row) string { +func ExportTable(header table.Row, rows []table.Row, footer table.Row) string { if len(rows) > 0 { t := CreateTable(header, rows, footer) return t.Render()