Upsun User Documentation

Continuous profiling for Go

Upsun Beta access

Test and provide feedback for our newest offering - Upsun!

You can register for the Beta by clicking here and completing the form.

Sign up for Beta access

Continuous profiling on Upsun Anchor to this heading

Upsun Continuous Profiler is powered by Blackfire. It is available directly from the Console under the Profiling tab of your environments.

The GO continuous profiling is currently made accross 6 dimensions:

  • Allocations: Number of objects allocated
  • Allocated Memory: Number of bytes allocated
  • CPU: Time spent running on the CPU
  • Goroutines: Number of goroutines (both on-CPU and off-CPU)
  • Heap Live Objects: Number of objects allocated that are not yet garbage collected.
  • Heap Live Size: Number of bytes allocated that are not yet garbage collected.

Prerequisites Anchor to this heading

Upsun Continuous Profiler requires Go >=1.18.

Installation Anchor to this heading

Get the Blackfire Continuous Profiler Go library:

go get github.com/blackfireio/go-continuous-profiling

Go continuous profiler API Anchor to this heading

The Go continuous profiler API has two functions:

func Start(opts ...Option) error {}
func Stop() {}

func Start(opts ...Option) error Anchor to this heading

Start starts the continuous profiler probe. It collects profiling information and uploads it to the Blackfire Agent periodically.

profiler.Start(
       profiler.WithCPUDuration(3 * time.Second),
       profiler.WithCPUProfileRate(1000),
       profiler.WithProfileTypes(profiler.CPUProfile, profiler.HeapProfile, profiler.GoroutineProfile),
       profiler.WithLabels({
            "key1": "value1",
            "key2": "value2",
       }),
       profiler.WithUploadTimeout(5 * time.Second),
)
defer profiler.Stop()

The Start function accepts the following options:

  • WithCPUDuration: specifies the length at which to collect CPU profiles. The default is 45 seconds. Can also be set via the environment variable BLACKFIRE_CONPROF_CPU_DURATION.

  • WithCPUProfileRate: sets the CPU profiling rate to Hz samples per second. The default is defined by the Go runtime as 100 Hz. Can also be set via the environment variable BLACKFIRE_CONPROF_CPU_PROFILERATE.

  • WithProfileTypes: sets the profiler types. Multiple profile types can be set (profiler.CPUProfile, profiler.HeapProfile, profiler.GoroutineProfile). The default is Profiler.CPUProfile.

  • WithLabels: sets custom labels specific to the profile payload that is sent.

  • WithUploadTimeout: sets the upload timeout of the message that is sent to the Blackfire Agent. The default is 10 seconds. Can also be set via the environment variable BLACKFIRE_CONPROF_UPLOAD_TIMEOUT.

There is also some additional configuration that can be done using environment variables:

  • BLACKFIRE_LOG_FILE: Sets the log file. The default is logging to stderr.

  • BLACKFIRE_LOG_LEVEL: Sets the log level. The default is logging only errors.

func Stop() Anchor to this heading

Stops the continuous profiling probe.

A simple example application Anchor to this heading

  1. Get the Blackfire Continuous Profiler Go library
go get github.com/blackfireio/go-continuous-profiling
  1. Save the following code as main.go and run as follows:
go run main.go
package main

import (
	"crypto/md5"
	"encoding/hex"
	"io"
	"time"

	profiler "github.com/blackfireio/go-continuous-profiling"
)

func doSomethingCpuIntensive() {
	md5Hash := func(s string) string {
		h := md5.New()
		io.WriteString(h, s)
		return hex.EncodeToString(h.Sum(nil))
	}
	for i := 0; i < 1_000_000; i++ {
		md5Hash("UpsunIsCoolAndSoAreYou")
	}
}

func main() {
	err := profiler.Start(
		profiler.WithAppName("my-app"),
	)
	if err != nil {
		panic("Error while starting Profiler")
	}
	defer profiler.Stop()

	for i := 0; i < 15; i++ {
		doSomethingCpuIntensive()

		time.Sleep(1 * time.Second)
	}
}

Is this page helpful?