Focused Profiling in Go

Long-running applications are not always busy doing work. In the case of, for instance, web, serverless or microservice applications, the work is done on every request, and the processes are idle the rest of the time. Similarly, if the program is processing messages from the queue, it may be idle when it is waiting for messages.

In order to profile those specific activity intervals in a long-running application, a profiler should be started before the activity begins, which is not always automatically possible.

StackImpact agents start and stop profilers automatically. The goal of the profiler scheduler is to increase the probability of profiling the program when it is doing relevant work. This works well for applications with equally distributed workloads, but is not optimal for applications with intermittent activity such as HTTP request handling.

Profiling API

For these cases, the Go agent provides agent.Profile(), agent.ProfileWithName(name) as well as HTTP handler wrapper methods. Using them will tell the agent about relevant sections of the program execution. These calls only start and stop profilers if agent is active and the overhead requirements are met. The decision of which profiler to start (e.g. CPU profiler, memory allocation profiler, blocking call profiler) is also made by the agent.

Using focused profiling will not disable automatic profiling. Both may activate the profilers as long as the overhead limit is not reached for the profiling cycle.

Here is an example of a Go application that uses the API:

package main

import (
	"fmt"
	"net/http"

	"github.com/stackimpact/stackimpact-go"
)

var agent *stackimpact.Agent

func helloHandler(w http.ResponseWriter, r *http.Request) {
	span := agent.ProfileWithName("Hello handler")
	defer span.Stop()

	// handler code here

	fmt.Fprintf(w, "Hello world!")
}

func main() {
	agent = stackimpact.Start(stackimpact.Options{
		AgentKey: "agent key here",
		AppName: "My Go App",
	})

	http.HandleFunc("/hello", helloHandler) 
	http.ListenAndServe(":8080", nil)
}

Helper wrappers for HTTP handlers are available as well. See Go agent’s focused profiling API for more information.

Span timing

In addition to improved profiling precision, the timing of profiled spans is reported to the Dashboard and available in the Health / Spans section.

Screenshot

See Go application metrics reference for more information.