github.com/grafana/pyroscope@v1.18.0/docs/sources/configure-client/language-sdks/go_push.md (about) 1 --- 2 title: "Go (push mode)" 3 menuTitle: "Go (push mode)" 4 description: "Instrumenting Golang applications for continuous profiling." 5 weight: 10 6 aliases: 7 - /docs/phlare/latest/configure-client/language-sdks/go_push 8 --- 9 10 # Go (push mode) 11 12 Our Go Profiler is a cutting-edge tool designed to optimize Golang applications. 13 By integrating with Pyroscope, the profiler offers developers an in-depth view of their Go codebase, enabling real-time performance analysis. 14 This powerful tool is crucial for pinpointing inefficiencies, streamlining code execution, and ensuring peak performance in Go applications. 15 16 Pyroscope uses the standard `runtime/pprof` package to collect profiling data. 17 Refer to [the official documentation](https://golang.org/doc/diagnostics#profiling) for details. 18 19 {{< admonition type="note" >}} 20 Refer to [Available profiling types](https://grafana.com/docs/pyroscope/latest/configure-client/profile-types/) for a list of profile types supported by Go. 21 {{< /admonition >}} 22 23 ## Before you begin 24 25 To capture and analyze profiling data, you need either a hosted Pyroscope OSS server or a hosted [Pyroscope instance with Grafana Cloud Profiles](/products/cloud/profiles-for-continuous-profiling/) (requires a free Grafana Cloud account). 26 27 The Pyroscope server can be a local server for development or a remote server for production use. 28 29 30 ## Configure the Go client 31 32 To start profiling a Go application, you need to include the Go module in your app: 33 34 ```go 35 go get github.com/grafana/pyroscope-go 36 ``` 37 38 {{% admonition type="note" %}} 39 If you'd prefer to use Pull mode you can do so using [Grafana Alloy](https://grafana.com/docs/pyroscope/<PYROSCOPE_VERSION>/configure-client/grafana-alloy/). 40 {{% /admonition %}} 41 42 Add the following code to your application: 43 44 ```go 45 package main 46 47 import "github.com/grafana/pyroscope-go" 48 49 func main() { 50 // These 2 lines are only required if you're using mutex or block profiling 51 // Read the explanation below for how to set these rates: 52 runtime.SetMutexProfileFraction(5) 53 runtime.SetBlockProfileRate(5) 54 55 pyroscope.Start(pyroscope.Config{ 56 ApplicationName: "simple.golang.app", 57 58 // replace this with the address of pyroscope server 59 ServerAddress: "http://pyroscope-server:4040", 60 61 // you can disable logging by setting this to nil 62 Logger: pyroscope.StandardLogger, 63 64 // you can provide static tags via a map: 65 Tags: map[string]string{"hostname": os.Getenv("HOSTNAME")}, 66 67 ProfileTypes: []pyroscope.ProfileType{ 68 // these profile types are enabled by default: 69 pyroscope.ProfileCPU, 70 pyroscope.ProfileAllocObjects, 71 pyroscope.ProfileAllocSpace, 72 pyroscope.ProfileInuseObjects, 73 pyroscope.ProfileInuseSpace, 74 75 // these profile types are optional: 76 pyroscope.ProfileGoroutines, 77 pyroscope.ProfileMutexCount, 78 pyroscope.ProfileMutexDuration, 79 pyroscope.ProfileBlockCount, 80 pyroscope.ProfileBlockDuration, 81 }, 82 }) 83 84 // your code goes here 85 } 86 ``` 87 88 Alternatively, if you want more control over the profiling process, you can manually handle the profiler initialization and termination: 89 90 ```go 91 profiler, err := pyroscope.Start(pyroscope.Config{ 92 // omitted for brevity 93 }) 94 if err != nil { 95 // the only reason this would fail is if the configuration is not valid 96 log.Fatalf("failed to start Pyroscope: %v", err) 97 } 98 defer profiler.Stop() 99 100 // your code goes here 101 } 102 ``` 103 104 This approach may be necessary if you need to ensure that the last profile is sent before the application exits. 105 106 ### Add profiling labels to your application 107 108 You can add tags (labels) to the profiling data. These tags can be used to filter the data in the UI. There is a custom API that's in line with the go-native pprof API: 109 110 ```go 111 // these two ways of adding tags are equivalent: 112 pyroscope.TagWrapper(context.Background(), pyroscope.Labels("controller", "slow_controller"), func(c context.Context) { 113 slowCode() 114 }) 115 116 pprof.Do(context.Background(), pprof.Labels("controller", "slow_controller"), func(c context.Context) { 117 slowCode() 118 }) 119 ``` 120 121 ### Mutex profiling 122 123 Mutex profiling is useful for finding sources of contention within your application. It helps you find out which mutexes are being held by which goroutines. 124 125 To enable mutex profiling, you need to add the following code to your application: 126 127 ```go 128 runtime.SetMutexProfileFraction(rate) 129 ``` 130 131 The `rate` parameter controls the fraction of mutex contention events that are reported in the mutex profile. On average, 1/rate events are reported. 132 133 ### Block profiling 134 135 Block profiling lets you analyze how much time your program spends waiting on the blocking operations such as: 136 137 * select 138 * channel send/receive 139 * semacquire 140 * notifyListWait 141 142 To enable block profiling, you need to add the following code to your application: 143 144 ```go 145 runtime.SetBlockProfileRate(rate) 146 ``` 147 148 The `rate` parameter controls the fraction of goroutine blocking events that are reported in the blocking profile. 149 The profiler aims to sample an average of one blocking event per rate nanoseconds spent blocked. 150 151 ## Send data to Pyroscope OSS or Grafana Cloud Profiles 152 153 To configure the Golang SDK to send data to Pyroscope, replace the `<URL>` placeholder with the appropriate server URL. 154 This could be the Grafana Cloud URL or your own custom Pyroscope server URL. 155 156 If you need to send data to Grafana Cloud, you'll have to configure HTTP Basic authentication. 157 Replace `<User>` with your Grafana Cloud stack user and `<Password>` with your Grafana Cloud API key. 158 159 If your Pyroscope server has multi-tenancy enabled, you'll need to configure a tenant ID. 160 Replace `<TenantID>` with your Pyroscope tenant ID. 161 162 ```go 163 pyroscope.Start(pyroscope.Config{ 164 ApplicationName: "example.golang.app", 165 ServerAddress: "<URL>", 166 // Optional HTTP Basic authentication 167 BasicAuthUser: "<User>", 168 BasicAuthPassword: "<Password>", 169 // Optional Pyroscope tenant ID (only needed if using multi-tenancy). Not needed for Grafana Cloud. 170 // TenantID: "<TenantID>", 171 ProfileTypes: []pyroscope.ProfileType{ 172 pyroscope.ProfileCPU, 173 pyroscope.ProfileInuseObjects, 174 pyroscope.ProfileAllocObjects, 175 pyroscope.ProfileInuseSpace, 176 pyroscope.ProfileAllocSpace, 177 }, 178 }) 179 ``` 180 181 ### Locate the URL, user, and password in Grafana Cloud Profiles 182 183 [//]: # 'Shared content for URl location in Grafana Cloud Profiles' 184 [//]: # 'This content is located in /pyroscope/docs/sources/shared/locate-url-pw-user-cloud-profiles.md' 185 186 {{< docs/shared source="pyroscope" lookup="locate-url-pw-user-cloud-profiles.md" version="latest" >}} 187 188 ### Option: Use `DisableGCRuns` for handling increased memory usage 189 190 Pyroscope may require additional resources when tracking a lot of objects. For example, a Go service that indexes large amounts of data requires more memory. 191 This tracking can lead to higher CPU usage and potential CPU throttling. 192 193 You can use `DisableGCRuns` in your Go configuration to disable automatic runtimes. 194 If this flag is activated, there is less GC running and therefore less CPU resources spent. 195 However, the heap profile may be less precise. 196 197 #### Background 198 199 In Go's pprof heap profiling, forcing garbage collection (GC) ensures accurate memory usage snapshots by removing uncollected objects. 200 Without this step, the heap profile may include memory that has been allocated but is no longer in use--objects that stay in memory simply because they haven't been collected yet. 201 This can mask or mimic memory leaks and introduce bias into the profiles, complicating their analysis. 202 Therefore, Pyroscope defaults to forcing GC every time a heap profile is collected. 203 204 However, in some cases, forcing GC can increase CPU usage, especially if there are many live objects in the heap. 205 This issue is reflected by the appearance of the `runtime.GC` function in the CPU profile. 206 If the problem has manifested, and some inaccuracy in the heap profile is acceptable, then it is advisable to disable this option to avoid performance degradation. 207 208 #### Activate `DisableGCRuns` 209 210 Add `DisableGCRuns: true` to the `pyroscope.Start(pyroscope.Config)` block. 211 212 ```go 213 pyroscope.Start(pyroscope.Config{ 214 ApplicationName: "example.golang.app", 215 ServerAddress: "<URL>", 216 // Disable automatic runtime.GC runs between getting the heap profiles. 217 DisableGCRuns: true, 218 ``` 219 220 ## Golang profiling examples 221 222 Check out the following resources to learn more about Golang profiling: 223 224 * [Golang examples](https://github.com/grafana/pyroscope/tree/main/examples/language-sdk-instrumentation/golang-push) 225 * [Golang Demo](https://play.grafana.org/a/grafana-pyroscope-app/single?query=process_cpu%3Acpu%3Ananoseconds%3Acpu%3Ananoseconds%7Bservice_name%3D%22pyroscope-rideshare-go%22%7D&from=now-1h&until=now) showing golang example with tags