github.com/grafana/pyroscope@v1.18.0/examples/language-sdk-instrumentation/golang-push/migrating-from-standard-pprof/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"runtime"
     8  	"sync"
     9  	"time"
    10  
    11  	"github.com/grafana/pyroscope-go" // replace "net/http/pprof" with Pyroscope SDK
    12  )
    13  
    14  func busyWork(d time.Duration) {
    15  	end := time.Now().Add(d)
    16  	for time.Now().Before(end) {
    17  		// Busy loop
    18  	}
    19  }
    20  
    21  func gatherClues(wg *sync.WaitGroup) {
    22  	defer wg.Done()
    23  	fmt.Println("Gathering clues...")
    24  	busyWork(500 * time.Millisecond)
    25  }
    26  
    27  func analyzeEvidence(wg *sync.WaitGroup) {
    28  	defer wg.Done()
    29  	fmt.Println("Analyzing evidence...")
    30  	busyWork(1 * time.Second)
    31  }
    32  
    33  func interviewWitnesses(wg *sync.WaitGroup) {
    34  	defer wg.Done()
    35  	fmt.Println("Interviewing witnesses...")
    36  	busyWork(1 * time.Second)
    37  }
    38  
    39  func chaseSuspect(wg *sync.WaitGroup) {
    40  	defer wg.Done()
    41  	fmt.Println("Chasing the suspect...")
    42  	busyWork(2 * time.Second)
    43  }
    44  
    45  func solveMystery(wg *sync.WaitGroup) {
    46  	defer wg.Done()
    47  	fmt.Println("Solving the mystery...")
    48  	busyWork(2 * time.Second)
    49  }
    50  
    51  func main() {
    52  	// These 2 lines are only required if you're using mutex or block profiling
    53  	runtime.SetMutexProfileFraction(5)
    54  	runtime.SetBlockProfileRate(5)
    55  
    56  	// Pyroscope configuration
    57  	profiler, err := pyroscope.Start(pyroscope.Config{
    58  		ApplicationName: "detective.mystery.app",
    59  		ServerAddress:   "https://profiles-prod-001.grafana.net", // If OSS, then "http://pyroscope.local:4040"
    60  		// Optional HTTP Basic authentication
    61  		// BasicAuthUser:     "<User>",     // 900009
    62  		// BasicAuthPassword: "<Password>", // glc_SAMPLEAPIKEY0000000000==
    63  		Logger: pyroscope.StandardLogger,
    64  		Tags:   map[string]string{"hostname": os.Getenv("HOSTNAME")},
    65  		ProfileTypes: []pyroscope.ProfileType{
    66  			pyroscope.ProfileCPU,
    67  			pyroscope.ProfileAllocObjects,
    68  			pyroscope.ProfileAllocSpace,
    69  			pyroscope.ProfileInuseObjects,
    70  			pyroscope.ProfileInuseSpace,
    71  			pyroscope.ProfileGoroutines,
    72  			pyroscope.ProfileMutexCount,
    73  			pyroscope.ProfileMutexDuration,
    74  			pyroscope.ProfileBlockCount,
    75  			pyroscope.ProfileBlockDuration,
    76  		},
    77  	})
    78  	if err != nil {
    79  		log.Fatalf("Error starting profiler: %v", err)
    80  	}
    81  	defer func() {
    82  		err := profiler.Stop()
    83  		if err != nil {
    84  			log.Printf("Error stopping profiler: %v", err)
    85  		}
    86  	}()
    87  
    88  	// pyroscope.Start is non-blocking: the profiler will start shortly.
    89  	// To ensure we don't miss the investigation, we wait briefly.
    90  	time.Sleep(time.Second)
    91  
    92  	var wg sync.WaitGroup
    93  	wg.Add(5) // Adding 5 detective tasks
    94  	go gatherClues(&wg)
    95  	go analyzeEvidence(&wg)
    96  	go interviewWitnesses(&wg)
    97  	go chaseSuspect(&wg)
    98  	go solveMystery(&wg)
    99  
   100  	wg.Wait() // Wait for all detective tasks to complete
   101  	fmt.Println("Mystery solved!")
   102  }