Skip to main content

Go

Pyroscope uses the standard runtime/pprof package to collect profiling data. Refer to the official documentation for details.

Supported platforms#

Spy NameTypeLinuxmacOSWindowsDocker
n/astandaloneโœ…โœ…โœ…โœ…

Profiling Go application#

To start profiling a Go application, you need to include our go module in your app:

# make sure you also upgrade pyroscope server to version 0.3.1 or highergo get github.com/pyroscope-io/client/pyroscope

Then add the following code to your application:

package main
import "github.com/pyroscope-io/client/pyroscope"
func main() {  // These 2 lines are only required if you're using mutex or block profiling  // Read the explanation below for how to set these rates:  runtime.SetMutexProfileFraction(5)  runtime.SetBlockProfileRate(5)
  pyroscope.Start(pyroscope.Config{    ApplicationName: "simple.golang.app",
    // replace this with the address of pyroscope server    ServerAddress:   "http://pyroscope-server:4040",
    // you can disable logging by setting this to nil    Logger:          pyroscope.StandardLogger,
    // optionally, if authentication is enabled, specify the API key:    // AuthToken: os.Getenv("PYROSCOPE_AUTH_TOKEN"),
    ProfileTypes: []pyroscope.ProfileType{      // these profile types are enabled by default:      pyroscope.ProfileCPU,      pyroscope.ProfileAllocObjects,      pyroscope.ProfileAllocSpace,      pyroscope.ProfileInuseObjects,      pyroscope.ProfileInuseSpace,
      // these profile types are optional:      pyroscope.ProfileGoroutines,      pyroscope.ProfileMutexCount,      pyroscope.ProfileMutexDuration,      pyroscope.ProfileBlockCount,      pyroscope.ProfileBlockDuration,    },  })
  // your code goes here}
important

If you want to use mutex or block profiling you have to explicitly enable it in your application. See Mutex Profiling section for more information.

important

Before golang 1.19 version, goroutine profile will lead to a long time STW proportional to the number of goroutines, see here for more details.

Tags#

It is possible to add tags (labels) to the profiling data. These tags can be used to filter the data in the UI. We have a custom API that's in line with our other integrations (e.g Python or Ruby) as well as go-native pprof api:

// these two ways of adding tags are equivalent:pyroscope.TagWrapper(context.Background(), pyroscope.Labels("controller", "slow_controller"), func(c context.Context) {  slowCode()})
pprof.Do(context.Background(), pprof.Labels("controller", "slow_controller"), func(c context.Context) {  slowCode()})

Pull Mode#

Go integration supports pull mode, which means that you can profile applications without adding any extra code. For that to work you will need to make sure you have profiling routes (/debug/pprof) enabled in your http server. Generally, that means that you need to add net/http/pprof package:

import _ "net/http/pprof"

Tracing Integraiton#

Pyroscope can integrate with distributed tracing systems supporting OpenTelemetry standard which allows you to link traces with the profiling data, and find specific lines of code related to a performance issue. For more information, refer to tracing integration documentation.

Mutex Profiling#

note

Mutex profiling requires pyroscope v0.20.0 or higher and client integration v.0.3.0 or higher.

Mutex profiling is useful for finding sources of contention within your application. It helps you to find out which mutexes are being held by which goroutines.

To enable mutex profiling, you need to add the following code to your application:

runtime.SetMutexProfileFraction(rate)

rate parameter controls the fraction of mutex contention events that are reported in the mutex profile. On average 1/rate events are reported.

Block Profiling#

note

Block profiling requires pyroscope v0.20.0 or higher and client integration v.0.3.0 or higher.

Block profiling lets you analyze how much time your program spends waiting on the blocking operations such as:

  • select
  • channel send/receive
  • semacquire
  • notifyListWait

To enable block profiling, you need to add the following code to your application:

runtime.SetBlockProfileRate(rate)

rate parameter controls the fraction of goroutine blocking events that are reported in the blocking profile. The profiler aims to sample an average of one blocking event per rate nanoseconds spent blocked.

Examples#

Check out the examples directory in our repository to learn more ๐Ÿ”ฅ