Skip to content

Commit

Permalink
Merge pull request #2746 from jsternberg/buildx-profiles
Browse files Browse the repository at this point in the history
pprof: take cpu and memory profiles by setting environment variables
  • Loading branch information
crazy-max authored Oct 25, 2024
2 parents 746eadd + cf7a9aa commit 658ed58
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 6 deletions.
75 changes: 75 additions & 0 deletions cmd/buildx/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package main

import (
"context"
"os"
"runtime"
"runtime/pprof"

"github.com/moby/buildkit/util/bklog"
"github.com/sirupsen/logrus"
)

func setupDebugProfiles(ctx context.Context) (stop func()) {
var stopFuncs []func()
if fn := setupCPUProfile(ctx); fn != nil {
stopFuncs = append(stopFuncs, fn)
}
if fn := setupHeapProfile(ctx); fn != nil {
stopFuncs = append(stopFuncs, fn)
}
return func() {
for _, fn := range stopFuncs {
fn()
}
}
}

func setupCPUProfile(ctx context.Context) (stop func()) {
if cpuProfile := os.Getenv("BUILDX_CPU_PROFILE"); cpuProfile != "" {
f, err := os.Create(cpuProfile)
if err != nil {
bklog.G(ctx).Warn("could not create cpu profile", logrus.WithError(err))
return nil
}

if err := pprof.StartCPUProfile(f); err != nil {
bklog.G(ctx).Warn("could not start cpu profile", logrus.WithError(err))
_ = f.Close()
return nil
}

return func() {
pprof.StopCPUProfile()
if err := f.Close(); err != nil {
bklog.G(ctx).Warn("could not close file for cpu profile", logrus.WithError(err))
}
}
}
return nil
}

func setupHeapProfile(ctx context.Context) (stop func()) {
if heapProfile := os.Getenv("BUILDX_MEM_PROFILE"); heapProfile != "" {
// Memory profile is only created on stop.
return func() {
f, err := os.Create(heapProfile)
if err != nil {
bklog.G(ctx).Warn("could not create memory profile", logrus.WithError(err))
return
}

// get up-to-date statistics
runtime.GC()

if err := pprof.WriteHeapProfile(f); err != nil {
bklog.G(ctx).Warn("could not write memory profile", logrus.WithError(err))
}

if err := f.Close(); err != nil {
bklog.G(ctx).Warn("could not close file for memory profile", logrus.WithError(err))
}
}
}
return nil
}
18 changes: 12 additions & 6 deletions cmd/buildx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,28 @@ func runPlugin(cmd *command.DockerCli) error {
})
}

func run(cmd *command.DockerCli) error {
stopProfiles := setupDebugProfiles(context.TODO())
defer stopProfiles()

if plugin.RunningStandalone() {
return runStandalone(cmd)
}
return runPlugin(cmd)
}

func main() {
cmd, err := command.NewDockerCli()
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

if plugin.RunningStandalone() {
err = runStandalone(cmd)
} else {
err = runPlugin(cmd)
}
if err == nil {
if err = run(cmd); err == nil {
return
}

// Check the error from the run function above.
if sterr, ok := err.(cli.StatusError); ok {
if sterr.Status != "" {
fmt.Fprintln(cmd.Err(), sterr.Status)
Expand Down

0 comments on commit 658ed58

Please sign in to comment.