mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	Merge pull request #2746 from jsternberg/buildx-profiles
pprof: take cpu and memory profiles by setting environment variables
This commit is contained in:
		
							
								
								
									
										75
									
								
								cmd/buildx/debug.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								cmd/buildx/debug.go
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -73,6 +73,16 @@ 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() {
 | 
					func main() {
 | 
				
			||||||
	cmd, err := command.NewDockerCli()
 | 
						cmd, err := command.NewDockerCli()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -80,15 +90,11 @@ func main() {
 | 
				
			|||||||
		os.Exit(1)
 | 
							os.Exit(1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if plugin.RunningStandalone() {
 | 
						if err = run(cmd); err == nil {
 | 
				
			||||||
		err = runStandalone(cmd)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		err = runPlugin(cmd)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check the error from the run function above.
 | 
				
			||||||
	if sterr, ok := err.(cli.StatusError); ok {
 | 
						if sterr, ok := err.(cli.StatusError); ok {
 | 
				
			||||||
		if sterr.Status != "" {
 | 
							if sterr.Status != "" {
 | 
				
			||||||
			fmt.Fprintln(cmd.Err(), sterr.Status)
 | 
								fmt.Fprintln(cmd.Err(), sterr.Status)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user