Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PerfSpect is a performance analysis tool for Linux systems written in Go. It pro
- `metrics`: Collects CPU performance metrics using hardware performance counters
- `report`: Generates system configuration and health (performance) from collected data
- `telemetry`: Gathers system telemetry data
- `flame`: Creates CPU flamegraphs
- `flamegraph`: Creates CPU flamegraphs
- `lock`: Analyzes lock contention
- `config`: Modifies system configuration for performance tuning

Expand All @@ -15,7 +15,7 @@ The tool can target both local and remote systems via SSH.
## Project Structure

- `main.go` - Application entry point
- `cmd/` - Command implementations (metrics, report, telemetry, flame, lock, config)
- `cmd/` - Command implementations (metrics, report, telemetry, flamegraph, lock, config)
- `internal/` - Internal packages (common, cpus, progress, report, script, table, target, util)
- `internal/common/` - Shared types, functions, and workflows for commands
- `internal/target/` - Abstraction for local and remote target systems
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Usage:
| [`metrics`](#metrics-command) | CPU core and uncore metrics |
| [`report`](#report-command) | System configuration and health |
| [`telemetry`](#telemetry-command) | System telemetry |
| [`flame`](#flame-command) | Software call-stacks as flamegraphs |
| [`flamegraph`](#flamegraph-command) | Software call-stacks as flamegraphs |
| [`lock`](#lock-command) | Software hot spot, cache-to-cache and lock contention |
| [`config`](#config-command) | Modify system configuration |

Expand Down Expand Up @@ -109,10 +109,10 @@ The `telemetry` command reports CPU utilization, instruction mix, disk stats, ne

![screenshot of the CPU utilization chart from the HTML output of the telemetry command](docs/telemetry_html.png)

#### Flame Command
Software flamegraphs are useful in diagnosing software performance bottlenecks. Run `perfspect flame` to capture a system-wide software flamegraph.
#### Flamegraph Command
Software flamegraphs are useful in diagnosing software performance bottlenecks. Run `perfspect flamegraph` to capture a system-wide software flamegraph.

![screenshot of a flame graph from the HTML output of the flame command](docs/flamegraph.png)
![screenshot of a flamegraph from the HTML output of the flamegraph command](docs/flamegraph.png)

#### Lock Command
As systems contain more and more cores, it can be useful to analyze the Linux kernel lock overhead and potential false-sharing that impacts system scalability. Run `perfspect lock` to collect system-wide hot spot, cache-to-cache and lock contention information. Experienced performance engineers can analyze the collected information to identify bottlenecks.
Expand Down
2 changes: 1 addition & 1 deletion cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var examples = []string{

var Cmd = &cobra.Command{
Use: cmdName,
Short: "Modify target(s) system configuration",
Short: "Modify system configuration on target(s)",
Long: `Sets system configuration items on target platform(s).

USE CAUTION! Target may become unstable. It is up to the user to ensure that the requested configuration is valid for the target. There is not an automated way to revert the configuration changes. If all else fails, reboot the target.`,
Expand Down
2 changes: 1 addition & 1 deletion cmd/config/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ var restoreExamples = []string{

var RestoreCmd = &cobra.Command{
Use: restoreCmdName + " <file>",
Short: "Restore system configuration from a previously recorded file",
Short: "Restore system configuration from file",
Long: `Restores system configuration from a file that was previously recorded using the --record flag.

The restore command will parse the configuration file, validate the settings against the target system,
Expand Down
9 changes: 5 additions & 4 deletions cmd/flame/flame.go → cmd/flamegraph/flamegraph.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Package flame is a subcommand of the root command. It is used to generate flamegraphs from target(s).
package flame
// Package flamegraph is a subcommand of the root command. It is used to generate flamegraphs from target(s).
package flamegraph

// Copyright (C) 2021-2025 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
Expand All @@ -19,7 +19,7 @@ import (
"github.com/spf13/pflag"
)

const cmdName = "flame"
const cmdName = "flamegraph"

var examples = []string{
fmt.Sprintf(" Flamegraph from local host: $ %s %s", common.AppName, cmdName),
Expand All @@ -29,7 +29,8 @@ var examples = []string{

var Cmd = &cobra.Command{
Use: cmdName,
Short: "Generate flamegraphs from target(s)",
Aliases: []string{"flame"},
Short: "Collect flamegraph data from target(s)",
Long: "",
Example: strings.Join(examples, "\n"),
RunE: runCmd,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package flame
package flamegraph

// Copyright (C) 2021-2025 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package flame
package flamegraph

// Copyright (C) 2021-2025 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause
Expand Down
2 changes: 1 addition & 1 deletion cmd/lock/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ var examples = []string{

var Cmd = &cobra.Command{
Use: cmdName,
Short: "Collect system information for kernel lock analysis from target(s)",
Short: "Collect kernel lock data from target(s)",
Long: "",
Example: strings.Join(examples, "\n"),
RunE: runCmd,
Expand Down
26 changes: 26 additions & 0 deletions cmd/lock/lock_renderers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package lock

// Copyright (C) 2021-2025 Intel Corporation
// SPDX-License-Identifier: BSD-3-Clause

import (
htmltemplate "html/template"
"perfspect/internal/report"
"perfspect/internal/table"
)

func kernelLockAnalysisHTMLRenderer(tableValues table.TableValues, targetName string) string {
values := [][]string{}
var tableValueStyles [][]string
for _, field := range tableValues.Fields {
rowValues := []string{}
rowValues = append(rowValues, field.Name)
rowValues = append(rowValues, htmltemplate.HTMLEscapeString(field.Values[0]))
values = append(values, rowValues)
rowStyles := []string{}
rowStyles = append(rowStyles, "font-weight:bold")
rowStyles = append(rowStyles, "white-space: pre-wrap")
tableValueStyles = append(tableValueStyles, rowStyles)
}
return report.RenderHTMLTable([]string{}, values, "pure-table pure-table-striped", tableValueStyles)
}
18 changes: 0 additions & 18 deletions cmd/lock/lock_tables.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ package lock
// SPDX-License-Identifier: BSD-3-Clause

import (
htmltemplate "html/template"
"perfspect/internal/common"
"perfspect/internal/report"
"perfspect/internal/script"
"perfspect/internal/table"
"strings"
Expand Down Expand Up @@ -39,19 +37,3 @@ func kernelLockAnalysisTableValues(outputs map[string]script.ScriptOutput) []tab
}
return fields
}

func kernelLockAnalysisHTMLRenderer(tableValues table.TableValues, targetName string) string {
values := [][]string{}
var tableValueStyles [][]string
for _, field := range tableValues.Fields {
rowValues := []string{}
rowValues = append(rowValues, field.Name)
rowValues = append(rowValues, htmltemplate.HTMLEscapeString(field.Values[0]))
values = append(values, rowValues)
rowStyles := []string{}
rowStyles = append(rowStyles, "font-weight:bold")
rowStyles = append(rowStyles, "white-space: pre-wrap")
tableValueStyles = append(tableValueStyles, rowStyles)
}
return report.RenderHTMLTable([]string{}, values, "pure-table pure-table-striped", tableValueStyles)
}
4 changes: 2 additions & 2 deletions cmd/metrics/metrics.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Package metrics is a subcommand of the root command. It provides functionality to monitor core and uncore metrics on one target.
// Package metrics is a subcommand of the root command. It provides functionality to collect performance metrics from target(s).
package metrics

// Copyright (C) 2021-2025 Intel Corporation
Expand Down Expand Up @@ -51,7 +51,7 @@ var examples = []string{

var Cmd = &cobra.Command{
Use: cmdName,
Short: "Monitor core and uncore metrics from one target",
Short: "Collect performance metrics from target(s)",
Long: "",
Example: strings.Join(examples, "\n"),
RunE: runCmd,
Expand Down
2 changes: 1 addition & 1 deletion cmd/metrics/trim.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ var trimExamples = []string{

var trimCmd = &cobra.Command{
Use: trimCmdName,
Short: "Generate new summary reports from existing metrics collection by filtering to a specific time range",
Short: "Filter existing metrics to a time range",
Long: "",
Example: strings.Join(trimExamples, "\n"),
RunE: runTrimCmd,
Expand Down
2 changes: 1 addition & 1 deletion cmd/report/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ var examples = []string{

var Cmd = &cobra.Command{
Use: cmdName,
Short: "Generate configuration report for target(s)",
Short: "Collect configuration data from target(s)",
Example: strings.Join(examples, "\n"),
RunE: runCmd,
PreRunE: validateFlags,
Expand Down
6 changes: 3 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"time"

"perfspect/cmd/config"
"perfspect/cmd/flame"
"perfspect/cmd/flamegraph"
"perfspect/cmd/lock"
"perfspect/cmd/metrics"
"perfspect/cmd/report"
Expand All @@ -46,7 +46,7 @@ const (

var examples = []string{
fmt.Sprintf(" Generate a configuration report: $ %s report", common.AppName),
fmt.Sprintf(" Monitor micro-architectural metrics: $ %s metrics", common.AppName),
fmt.Sprintf(" Collect micro-architectural metrics: $ %s metrics", common.AppName),
fmt.Sprintf(" Generate a configuration report on a remote target: $ %s report --target 192.168.1.2 --user elaine --key ~/.ssh/id_rsa", common.AppName),
fmt.Sprintf(" Generate configuration reports for multiple remote targets: $ %s report --targets ./targets.yaml", common.AppName),
}
Expand Down Expand Up @@ -116,7 +116,7 @@ Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}}
rootCmd.AddCommand(report.Cmd)
rootCmd.AddCommand(metrics.Cmd)
rootCmd.AddCommand(telemetry.Cmd)
rootCmd.AddCommand(flame.Cmd)
rootCmd.AddCommand(flamegraph.Cmd)
rootCmd.AddCommand(lock.Cmd)
rootCmd.AddCommand(config.Cmd)
rootCmd.AddGroup([]*cobra.Group{{ID: "other", Title: "Other Commands:"}}...)
Expand Down
Loading