Skip to content

Commit 6130131

Browse files
authored
feature: highlight misconfigurations (#681)
Signed-off-by: Harper, Jason M <jason.m.harper@intel.com>
1 parent 29f0151 commit 6130131

File tree

2 files changed

+132
-3
lines changed

2 files changed

+132
-3
lines changed

cmd/report/report.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,8 @@ func runCmd(cmd *cobra.Command, args []string) error {
281281
}
282282

283283
report.RegisterHTMLRenderer(DIMMTableName, dimmTableHTMLRenderer)
284+
report.RegisterHTMLRenderer(SystemSummaryTableName, systemSummaryTableHTMLRenderer)
285+
report.RegisterHTMLMultiTargetRenderer(SystemSummaryTableName, systemSummaryTableHTMLMultiTargetRenderer)
284286

285287
return reportingCommand.Run()
286288
}

cmd/report/report_tables.go

Lines changed: 130 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
htmltemplate "html/template"
1111
"log/slog"
1212
"math"
13+
"regexp"
1314
"sort"
1415
"strconv"
1516
"strings"
@@ -844,7 +845,7 @@ func elcTableInsights(outputs map[string]script.ScriptOutput, tableValues table.
844845
if err != nil {
845846
slog.Warn(err.Error())
846847
} else {
847-
// warn if ELC mode is not set to 'Latency Optimized' or 'Default' consistently across all dies
848+
// warn if ELC mode is not set to 'Latency Optimized' or 'Optimized Power Mode' consistently across all dies
848849
firstMode := tableValues.Fields[modeFieldIndex].Values[0]
849850
for _, mode := range tableValues.Fields[modeFieldIndex].Values[1:] {
850851
if mode != firstMode {
@@ -855,7 +856,7 @@ func elcTableInsights(outputs map[string]script.ScriptOutput, tableValues table.
855856
break
856857
}
857858
}
858-
// suggest setting ELC mode to 'Latency Optimized' or 'Default' based on the current setting
859+
// suggest setting ELC mode to 'Latency Optimized' or 'Optimized Power Mode' based on the current setting
859860
for _, mode := range tableValues.Fields[modeFieldIndex].Values {
860861
if mode != "" && mode != extract.ELCModeLatencyOptimized {
861862
insights = append(insights, table.Insight{
@@ -1729,6 +1730,132 @@ func dimmDetails(dimm []string) (details string) {
17291730
return
17301731
}
17311732

1733+
var configuredSpeedPattern = regexp.MustCompile(`(\d+(?:\.\d+)?\s*MT/s)\s*\[(\d+(?:\.\d+)?\s*MT/s)\]`)
1734+
1735+
func highlightConfiguredSpeedMismatchesHTML(value string) string {
1736+
if value == "" {
1737+
return ""
1738+
}
1739+
1740+
matches := configuredSpeedPattern.FindAllStringSubmatchIndex(value, -1)
1741+
if len(matches) == 0 {
1742+
return htmltemplate.HTMLEscapeString(value)
1743+
}
1744+
1745+
var sb strings.Builder
1746+
last := 0
1747+
for _, match := range matches {
1748+
fullStart, fullEnd := match[0], match[1]
1749+
maxStart, maxEnd := match[2], match[3]
1750+
configuredStart, configuredEnd := match[4], match[5]
1751+
1752+
sb.WriteString(htmltemplate.HTMLEscapeString(value[last:fullStart]))
1753+
1754+
maxSpeed := strings.TrimSpace(value[maxStart:maxEnd])
1755+
configuredSpeed := strings.TrimSpace(value[configuredStart:configuredEnd])
1756+
if maxSpeed != "" && configuredSpeed != "" && maxSpeed != configuredSpeed {
1757+
sb.WriteString(htmltemplate.HTMLEscapeString(value[fullStart:configuredStart]))
1758+
sb.WriteString(`<span style="background-color:#fff3b0;font-weight:700">`)
1759+
sb.WriteString(htmltemplate.HTMLEscapeString(value[configuredStart:configuredEnd]))
1760+
sb.WriteString(`</span>`)
1761+
sb.WriteString(htmltemplate.HTMLEscapeString(value[configuredEnd:fullEnd]))
1762+
} else {
1763+
sb.WriteString(htmltemplate.HTMLEscapeString(value[fullStart:fullEnd]))
1764+
}
1765+
1766+
last = fullEnd
1767+
}
1768+
sb.WriteString(htmltemplate.HTMLEscapeString(value[last:]))
1769+
return sb.String()
1770+
}
1771+
1772+
// systemSummaryTableHTMLRenderer renders the System Summary table with special handling to highlight
1773+
// memory speed mismatches. It expects the "Installed Memory" and "System Summary" fields to contain
1774+
// values in the format of "<max speed> [<configured speed>]". If such a pattern is detected and the
1775+
// max speed differs from the configured speed, the configured speed will be highlighted in the HTML
1776+
// output.
1777+
func systemSummaryTableHTMLRenderer(tableValues table.TableValues, targetName string) string {
1778+
values := [][]string{}
1779+
var tableValueStyles [][]string
1780+
for _, field := range tableValues.Fields {
1781+
rowValues := []string{report.CreateFieldNameWithDescription(field.Name, field.Description)}
1782+
if len(field.Values) > 0 {
1783+
fieldValue := field.Values[0]
1784+
if field.Name == "Installed Memory" || field.Name == "System Summary" {
1785+
rowValues = append(rowValues, highlightConfiguredSpeedMismatchesHTML(fieldValue))
1786+
} else {
1787+
rowValues = append(rowValues, htmltemplate.HTMLEscapeString(fieldValue))
1788+
}
1789+
} else {
1790+
rowValues = append(rowValues, "")
1791+
}
1792+
values = append(values, rowValues)
1793+
tableValueStyles = append(tableValueStyles, []string{"font-weight:bold"})
1794+
}
1795+
_ = targetName
1796+
return report.RenderHTMLTable([]string{}, values, "pure-table pure-table-striped", tableValueStyles)
1797+
}
1798+
1799+
func systemSummaryTableHTMLMultiTargetRenderer(tableValues []table.TableValues, targetNames []string) string {
1800+
if len(tableValues) == 0 {
1801+
return ""
1802+
}
1803+
1804+
values := [][]string{}
1805+
var tableValueStyles [][]string
1806+
for fieldIndex, field := range tableValues[0].Fields {
1807+
rowValues := []string{report.CreateFieldNameWithDescription(field.Name, field.Description)}
1808+
for _, targetTableValues := range tableValues {
1809+
if len(targetTableValues.Fields) > fieldIndex && len(targetTableValues.Fields[fieldIndex].Values) > 0 {
1810+
fieldValue := targetTableValues.Fields[fieldIndex].Values[0]
1811+
if field.Name == "Installed Memory" || field.Name == "System Summary" {
1812+
rowValues = append(rowValues, highlightConfiguredSpeedMismatchesHTML(fieldValue))
1813+
} else {
1814+
rowValues = append(rowValues, htmltemplate.HTMLEscapeString(fieldValue))
1815+
}
1816+
} else {
1817+
rowValues = append(rowValues, "")
1818+
}
1819+
}
1820+
values = append(values, rowValues)
1821+
tableValueStyles = append(tableValueStyles, []string{"font-weight:bold"})
1822+
}
1823+
1824+
headers := []string{""}
1825+
headers = append(headers, targetNames...)
1826+
return report.RenderHTMLTable(headers, values, "pure-table pure-table-striped", tableValueStyles)
1827+
}
1828+
1829+
// dimmDetailsHTML takes the DIMM details string and returns an HTML-escaped version of it with the
1830+
// configured speed highlighted if it differs from the maximum speed.
1831+
func dimmDetailsHTML(details string) string {
1832+
if details == "No Module Installed" {
1833+
return htmltemplate.HTMLEscapeString(details)
1834+
}
1835+
1836+
matches := configuredSpeedPattern.FindAllStringSubmatchIndex(details, -1)
1837+
if len(matches) == 0 {
1838+
return htmltemplate.HTMLEscapeString(details)
1839+
}
1840+
match := matches[len(matches)-1]
1841+
if len(match) != 6 || match[1] != len(details) {
1842+
return htmltemplate.HTMLEscapeString(details)
1843+
}
1844+
1845+
maxSpeed := strings.TrimSpace(details[match[2]:match[3]])
1846+
configuredSpeed := strings.TrimSpace(details[match[4]:match[5]])
1847+
if maxSpeed == "" || configuredSpeed == "" || configuredSpeed == maxSpeed {
1848+
return htmltemplate.HTMLEscapeString(details)
1849+
}
1850+
1851+
// highlight configured speed when it differs from the DIMM maximum speed
1852+
return htmltemplate.HTMLEscapeString(details[:match[4]]) +
1853+
`<span style="background-color:#fff3b0;font-weight:700">` +
1854+
htmltemplate.HTMLEscapeString(details[match[4]:match[5]]) +
1855+
`</span>` +
1856+
htmltemplate.HTMLEscapeString(details[match[5]:])
1857+
}
1858+
17321859
func dimmTableHTMLRenderer(tableValues table.TableValues, targetName string) string {
17331860
if len(tableValues.Fields) <= max(extract.DerivedSocketIdx, extract.DerivedChannelIdx, extract.DerivedSlotIdx) ||
17341861
len(tableValues.Fields[extract.DerivedSocketIdx].Values) == 0 ||
@@ -1794,7 +1921,7 @@ func dimmTableHTMLRenderer(tableValues table.TableValues, targetName string) str
17941921
slotTableValuesStyles = append(slotTableValuesStyles, []string{})
17951922
for _, slot := range slotKeys {
17961923
dimmDetails := channelMap[slot]
1797-
slotTableValues[0] = append(slotTableValues[0], htmltemplate.HTMLEscapeString(dimmDetails))
1924+
slotTableValues[0] = append(slotTableValues[0], dimmDetailsHTML(dimmDetails))
17981925
var slotColor string
17991926
if dimmDetails == "No Module Installed" {
18001927
slotColor = "background-color:silver"

0 commit comments

Comments
 (0)