mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-08-08 22:36:49 +02:00
Make profiling easier (#3634)
Add a `-profile` command line flag, and some documentation about how to collect and view profile data.
This commit is contained in:
@@ -154,31 +154,7 @@ If you want to trigger a debug session from VSCode, you can use the following sn
|
||||
|
||||
## Profiling
|
||||
|
||||
If you want to investigate what's contributing to CPU usage you can add the following to the top of the `main()` function in `main.go`
|
||||
|
||||
```go
|
||||
import "runtime/pprof"
|
||||
|
||||
func main() {
|
||||
f, err := os.Create("cpu.prof")
|
||||
if err != nil {
|
||||
log.Fatal("could not create CPU profile: ", err)
|
||||
}
|
||||
defer f.Close()
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
log.Fatal("could not start CPU profile: ", err)
|
||||
}
|
||||
defer pprof.StopCPUProfile()
|
||||
...
|
||||
```
|
||||
|
||||
Then run lazygit, and afterwards, from your terminal, run:
|
||||
|
||||
```sh
|
||||
go tool pprof --web cpu.prof
|
||||
```
|
||||
|
||||
That should open an application which allows you to view the breakdown of CPU usage.
|
||||
If you want to investigate what's contributing to CPU or memory usage, see [this separate document](docs/dev/Profiling.md).
|
||||
|
||||
## Testing
|
||||
|
||||
|
69
docs/dev/Profiling.md
Normal file
69
docs/dev/Profiling.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Profiling Lazygit
|
||||
|
||||
If you want to investigate what's contributing to CPU or memory usage, start
|
||||
lazygit with the `-profile` command line flag. This tells it to start an
|
||||
integrated web server that listens for profiling requests.
|
||||
|
||||
## Save profile data
|
||||
|
||||
### CPU
|
||||
|
||||
While lazygit is running with the `-profile` flag, perform a CPU profile and
|
||||
save it to a file by running this command in another terminal window:
|
||||
|
||||
```sh
|
||||
curl -o cpu.out http://127.0.0.1:6060/debug/pprof/profile
|
||||
```
|
||||
|
||||
By default, it profiles for 30 seconds. To change the duration, use
|
||||
|
||||
```sh
|
||||
curl -o cpu.out 'http://127.0.0.1:6060/debug/pprof/profile?seconds=60'
|
||||
```
|
||||
|
||||
### Memory
|
||||
|
||||
To save a heap profile (containing information about all memory allocated so
|
||||
far since startup), use
|
||||
|
||||
```sh
|
||||
curl -o mem.out http://127.0.0.1:6060/debug/pprof/heap
|
||||
```
|
||||
|
||||
Sometimes it can be useful to get a delta log, i.e. to see how memory usage
|
||||
developed from one point in time to another. For that, use
|
||||
|
||||
```sh
|
||||
curl -o mem.out 'http://127.0.0.1:6060/debug/pprof/heap?seconds=20'
|
||||
```
|
||||
|
||||
This will log the memory usage difference between now and 20 seconds later, so
|
||||
it gives you 20 seconds to perform the action in lazygit that you are interested
|
||||
in measuring.
|
||||
|
||||
## View profile data
|
||||
|
||||
To display the profile data, you can either use speedscope.app, or the pprof
|
||||
tool that comes with go. I prefer the former because it has a nicer UI and is a
|
||||
little more powerful; however, I have seen cases where it wasn't able to load a
|
||||
profile for some reason, in which case it's good to have the pprof tool as a
|
||||
fallback.
|
||||
|
||||
### Speedscope.app
|
||||
|
||||
Go to https://www.speedscope.app/ in your browser, and drag the saved profile
|
||||
onto the browser window. Refer to [the
|
||||
documentation](https://github.com/jlfwong/speedscope?tab=readme-ov-file#usage)
|
||||
for how to navigate the data.
|
||||
|
||||
### Pprof tool
|
||||
|
||||
To view a profile that you saved as `cpu.out`, use
|
||||
|
||||
```sh
|
||||
go tool pprof -http=:8080 cpu.out
|
||||
```
|
||||
|
||||
By default this shows the graph view, which I don't find very useful myself.
|
||||
Choose "Flame Graph" from the View menu to show a much more useful
|
||||
representation of the data.
|
@@ -5,3 +5,4 @@
|
||||
* [Integration Tests](../../pkg/integration/README.md)
|
||||
* [Demo Recordings](./Demo_Recordings.md)
|
||||
* [Find base commit for fixup design](Find_Base_Commit_For_Fixup_Design.md)
|
||||
* [Profiling](Profiling.md)
|
||||
|
@@ -4,6 +4,8 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -30,6 +32,7 @@ type cliArgs struct {
|
||||
PrintVersionInfo bool
|
||||
Debug bool
|
||||
TailLogs bool
|
||||
Profile bool
|
||||
PrintDefaultConfig bool
|
||||
PrintConfigDir bool
|
||||
UseConfigDir string
|
||||
@@ -145,6 +148,14 @@ func Start(buildInfo *BuildInfo, integrationTest integrationTypes.IntegrationTes
|
||||
return
|
||||
}
|
||||
|
||||
if cliArgs.Profile {
|
||||
go func() {
|
||||
if err := http.ListenAndServe("localhost:6060", nil); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
parsedGitArg := parseGitArg(cliArgs.GitArg)
|
||||
|
||||
Run(appConfig, common, appTypes.NewStartArgs(cliArgs.FilterPath, parsedGitArg, integrationTest))
|
||||
@@ -171,6 +182,9 @@ func parseCliArgsAndEnvVars() *cliArgs {
|
||||
tailLogs := false
|
||||
flaggy.Bool(&tailLogs, "l", "logs", "Tail lazygit logs (intended to be used when `lazygit --debug` is called in a separate terminal tab)")
|
||||
|
||||
profile := false
|
||||
flaggy.Bool(&profile, "", "profile", "Start the profiler and serve it on http port 6060. See CONTRIBUTING.md for more info.")
|
||||
|
||||
printDefaultConfig := false
|
||||
flaggy.Bool(&printDefaultConfig, "c", "config", "Print the default config")
|
||||
|
||||
@@ -202,6 +216,7 @@ func parseCliArgsAndEnvVars() *cliArgs {
|
||||
PrintVersionInfo: printVersionInfo,
|
||||
Debug: debug,
|
||||
TailLogs: tailLogs,
|
||||
Profile: profile,
|
||||
PrintDefaultConfig: printDefaultConfig,
|
||||
PrintConfigDir: printConfigDir,
|
||||
UseConfigDir: useConfigDir,
|
||||
|
Reference in New Issue
Block a user