Continuous profiling for Go
Back to home
On this page
Feature Availability
By default, Upsun offers 15 minutes of continuous profiling per project and for free. To get 30 days of continuous profiling per project and for a fixed fee, upgrade to the Continuous Profiling add-on.
Continuous profiling on Upsun
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 across 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
The default sampling frequency is 100 Hz. This means the Go continuous profiler is collecting information 100 times per second.
Prerequisites
Upsun Continuous Profiler requires Go >=1.18
.
Installation
Get the Blackfire Continuous Profiler Go library:
go get github.com/blackfireio/go-continuous-profiling
Go continuous profiler API
The Go continuous profiler API has two functions:
func Start(opts ...Option) error {}
func Stop() {}
func Start(opts ...Option) error
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 variableBLACKFIRE_CONPROF_CPU_DURATION
. -
WithCPUProfileRate
: sets the CPU profiling rate in Hz (number of samples per second). The default is defined by the Go runtime as 100 Hz. Can also be set via the environment variableBLACKFIRE_CONPROF_CPU_PROFILERATE
. -
WithProfileTypes
: sets the profiler types. Multiple profile types can be set (profiler.CPUProfile
,profiler.HeapProfile
,profiler.GoroutineProfile
). The default isProfiler.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 variableBLACKFIRE_CONPROF_UPLOAD_TIMEOUT
.
Note:
If the same parameter is set by both an environment variable and a Start
call, the explicit
parameter in the Start
call takes precedence.
There is also some additional configuration that can be done using environment variables:
-
BLACKFIRE_LOG_FILE
: Sets the log file. The default is logging tostderr
. -
BLACKFIRE_LOG_LEVEL
: Sets the log level. The default is logging only errors.
func Stop()
Stops the continuous profiling probe.
An example application
- Get the Blackfire Continuous Profiler Go library
go get github.com/blackfireio/go-continuous-profiling
- 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)
}
}