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