github.com/xyproto/orbiton/v2@v2.65.12-0.20240516144430-e10a419274ec/trace.go (about)

     1  //go:build trace
     2  
     3  package main
     4  
     5  import (
     6  	"log"
     7  	"os"
     8  	"runtime"
     9  	"runtime/pprof"
    10  	"time"
    11  
    12  	"net/http"
    13  	_ "net/http/pprof"
    14  
    15  	"github.com/felixge/fgtrace"
    16  	"github.com/spf13/pflag"
    17  )
    18  
    19  var (
    20  	cpuProfileFilename string
    21  	memProfileFilename string
    22  	fgtraceFilename    string
    23  	cpuProfileFile     os.File
    24  )
    25  
    26  func init() {
    27  	pflag.StringVarP(&cpuProfileFilename, "cpuprofile", "u", "", "write CPU profile to `file`")
    28  	pflag.StringVarP(&memProfileFilename, "memprofile", "e", "", "write memory profile to `file`")
    29  	pflag.StringVarP(&fgtraceFilename, "fgtrace", "g", "", "write fgtrace to `file`")
    30  
    31  	// Start the pprof HTTP server as well
    32  	go func() {
    33  		log.Println("Starting pprof server at :6060")
    34  		log.Println("Try: http://localhost:6060/debug/pprof/goroutine?debug=2")
    35  		log.Println(http.ListenAndServe(":6060", nil))
    36  	}()
    37  
    38  	// Give it some time to be able to show the log messages from the goroutine above
    39  	time.Sleep(1200 * time.Millisecond)
    40  }
    41  
    42  func traceStart() {
    43  	// Output CPU profile information, if a filename is given
    44  	if cpuProfileFilename != "" {
    45  		cpuProfileFile, err := os.Create(cpuProfileFilename)
    46  		if err != nil {
    47  			log.Fatal("could not create CPU profile: ", err)
    48  		}
    49  
    50  		// Set the rate and start profiling the CPU usage
    51  		// runtime.SetCPUProfileRate(500)
    52  		if err := pprof.StartCPUProfile(cpuProfileFile); err != nil {
    53  			log.Fatal("could not start CPU profile: ", err)
    54  		}
    55  	}
    56  
    57  	if fgtraceFilename != "" {
    58  		defer fgtrace.Config{Dst: fgtrace.File(fgtraceFilename)}.Trace().Stop()
    59  	}
    60  }
    61  
    62  func traceComplete() {
    63  	// Output memory profile information, if a filename is given
    64  	if memProfileFilename != "" {
    65  		f, err := os.Create(memProfileFilename)
    66  		if err != nil {
    67  			log.Fatal("could not create memory profile: ", err)
    68  			logf("could not create memory profile: %v\n", err)
    69  		}
    70  		defer f.Close() // error handling omitted for example
    71  		runtime.GC()    // get up-to-date statistics
    72  		if err := pprof.WriteHeapProfile(f); err != nil {
    73  			log.Fatal("could not write to memory profile: ", err)
    74  			logf("could not write to memory profile: %v\n", err)
    75  		}
    76  	}
    77  	if cpuProfileFilename != "" {
    78  		pprof.StopCPUProfile()
    79  		cpuProfileFile.Close()
    80  	}
    81  }