OpenObserve Docs
IngestionProfiles

Go Profiling

Go has two paths:

PathWhen to use
pprof (this page)CPU, heap, mutex, and block; expose /debug/pprof
eBPF profilerOn-CPU and off-CPU; no code changes (Linux)

Expose pprof

Burns CPU so the flame graph has samples:

package main

import (
	"crypto/sha256"
	"net/http"
	_ "net/http/pprof"
)

func main() {
	go func() {
		_ = http.ListenAndServe("127.0.0.1:6060", nil)
	}()

	buf := []byte("openobserve")
	for {
		sum := sha256.Sum256(buf)
		buf = sum[:]
	}
}
go mod init pprofdemo
go mod tidy
go run .

Scrape with the Collector

Copy the endpoint and Authorization header from Data Sources → Custom → Profiles. Use otelcol-contrib 0.153+ (remote: scrape config). CPU scrape timeout must be longer than ?seconds= on the pprof URL.

receivers:
  pprof/cpu:
    remote:
      endpoint: http://127.0.0.1:6060/debug/pprof/profile?seconds=5
      collection_interval: 30s
      timeout: 60s

processors:
  resource:
    attributes:
      - key: service.name
        value: your-service
        action: upsert

exporters:
  otlp_http/openobserve:
    profiles_endpoint: http://<your-openobserve-host>/api/<your-org>/v1/profiles
    headers:
      Authorization: Basic <paste-from-Data-Sources>
      stream-name: default

service:
  pipelines:
    profiles:
      receivers: [pprof/cpu]
      processors: [resource]
      exporters: [otlp_http/openobserve]
otelcol-contrib --feature-gates=+service.profilesSupport --config=otelcol-config.yaml

Heap, allocs, mutex, and block

For mutex and block, call these at process start (CPU and heap work without them):

runtime.SetMutexProfileFraction(1)
runtime.SetBlockProfileRate(1)
ProfileEndpoint
CPU/debug/pprof/profile?seconds=5
Heap/debug/pprof/heap
Allocations/debug/pprof/allocs
Mutex/debug/pprof/mutex
Block/debug/pprof/block

Verify in OpenObserve

Go pprof CPU flame graph in OpenObserve

Next steps

Need some help?

Was this page helpful?

Last updated on

On this page