How to profile the golang program
For checkout the resources usage in golang, this is simple
Add the profile code in app
1// Add the flag to arguments to cpu and memory ptoto buffer file store to it
2 rootCmd.PersistentFlags().StringP("cpuprofile", "", "", "cpu profile file")
3 rootCmd.PersistentFlags().StringP("memprofile", "", "", "memory profile file")
4// whether enable profile
5func enableProfile() {
6 cpu, _ := rootCmd.Flags().GetString("cpuprofile")
7 mem, _ := rootCmd.Flags().GetString("memprofile")
8 if cpu != "" {
9 f, err := os.Create(cpu)
10 if err != nil {
11 log.Fatal().Msgf("Could not create CPU profile: %v", err)
12 }
13 if err := pprof.StartCPUProfile(f); err != nil {
14 log.Fatal().Msgf("Could not start CPU profile: %v", err)
15 }
16 }
17 if mem != "" {
18 f, err := os.Create(mem)
19 if err != nil {
20 log.Fatal().Msgf("Could not create Memory profile: %v", err)
21 }
22 runtime.GC()
23 if err := pprof.WriteHeapProfile(f); err != nil {
24 log.Fatal().Msgf("Could not write memory profile: %v", err)
25 }
26 f.Close()
27 }
28}
Use the Signal to generate the profile
1// registe the signal
2 exitApp := make(chan os.Signal, 1)
3 signal.Notify(exitApp, os.Interrupt, syscall.SIGTERM, syscall.SIGUSR1)
4 go listenForInterrupt(exitApp)
5
6 func listenForInterrupt(exitApp chan os.Signal) {
7 switch sig := <-exitApp; sig {
8 case os.Interrupt:
9 log.Fatal().Msg("Interrupt signal received. Exiting...")
10 case syscall.SIGUSR1:
11 pprof.StopCPUProfile() //when receive the SIGUSR1 signal to generate the profile
12 log.Warn().Msg("Stop the cpu profile")
13 default:
14 log.Fatal().Msgf("Unexpected signal %v received. Exiting...", sig)
15 }
16 cmd.HttpServer.Shutdown(context.TODO())
17 }
Copy the pprof file to local and analysis use go tool pprof
1# send the signal to terminate to profile
2kill -USR1 xxxxx
3# copy pprof from pod container to local
4kubectl cp namespace/pod-xxxxx-name:/tmp/cpu.prof ./cpu.pprof
5# launch the analysis tool view in browser
6go tool pprof -http=":8080" cpu.pprof
Use trace to view goroutines
1import "runtime/trace"
2
3// Start tracing.
4f, _ := os.Create("trace.out")
5trace.Start(f)
6defer trace.Stop()
7
8// open the browser to view
9// go tool trace trace.out