Pyroscope
Oodle supports continuous profiling through a Pyroscope-compatible ingestion endpoint. You can send CPU, memory, goroutine, mutex, and block profiles from any language that has a Pyroscope SDK — and visualize flame graphs directly in Grafana.
Prerequisites
You will need:
OODLE_INSTANCE— your Oodle instance ID. Find it under Settings → API Keys in the Oodle UI. (ap1, us1)OODLE_API_KEY— an API key for authentication. Choose one from the same page. (ap1, us1)OODLE_COLLECTOR— your collector domain (e.g.<INSTANCE>.collector.oodle.ai).
Send Profiles to Oodle
- Go
- Python
- Java
- Rust
- Grafana Alloy / Agent
Install the Pyroscope Go SDK:
go get github.com/grafana/pyroscope-go
Add the following to your application's main()
or initialization code:
import "github.com/grafana/pyroscope-go"
func main() {
pyroscope.Start(pyroscope.Config{
ApplicationName: "my-app",
ServerAddress:
"https://<OODLE_COLLECTOR>" +
"/v1/pyroscope/<OODLE_INSTANCE>",
AuthToken: "<OODLE_API_KEY>",
ProfileTypes: []pyroscope.ProfileType{
pyroscope.ProfileCPU,
pyroscope.ProfileAllocObjects,
pyroscope.ProfileAllocSpace,
pyroscope.ProfileInuseObjects,
pyroscope.ProfileInuseSpace,
pyroscope.ProfileGoroutines,
pyroscope.ProfileMutexCount,
pyroscope.ProfileMutexDuration,
pyroscope.ProfileBlockCount,
pyroscope.ProfileBlockDuration,
},
})
// ... your application code ...
}
Install the Pyroscope Python SDK:
pip install pyroscope-io
Add the following to your application startup:
import pyroscope
pyroscope.configure(
application_name="my-app",
server_address=(
"https://<OODLE_COLLECTOR>"
"/v1/pyroscope/<OODLE_INSTANCE>"
),
auth_token="<OODLE_API_KEY>",
)
Add the Pyroscope Java agent to your JVM startup flags:
java -javaagent:pyroscope.jar \
-Dpyroscope.application.name=my-app \
-Dpyroscope.server.address=\
https://<OODLE_COLLECTOR>/v1/pyroscope/<OODLE_INSTANCE> \
-Dpyroscope.auth.token=<OODLE_API_KEY> \
-jar my-app.jar
Download the latest pyroscope.jar from the
Grafana Pyroscope Java releases.
Add the Pyroscope crate with the pprof-rs backend to
your Cargo.toml:
[dependencies]
pyroscope = { version = "2.0", features = ["backend-pprof-rs"] }
Start pyroscope before the tokio runtime:
use pyroscope::pyroscope::PyroscopeAgentBuilder;
use pyroscope::backend::{
pprof_backend, PprofConfig, BackendConfig,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let agent = PyroscopeAgentBuilder::new(
"https://<OODLE_COLLECTOR>/v1/pyroscope/<OODLE_INSTANCE>",
"my-app",
100,
"pyroscope-rs",
env!("CARGO_PKG_VERSION"),
pprof_backend(
PprofConfig::default(),
BackendConfig::default(),
),
)
.basic_auth(
"Bearer".to_string(),
"<OODLE_API_KEY>".to_string(),
)
.build()?;
let _running = agent.start()?;
// Enter the tokio runtime AFTER pyroscope starts.
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?
.block_on(async_main())
}
If you run Grafana Alloy (or the legacy Grafana Agent), you can configure it to scrape pprof endpoints and forward profiles to Oodle:
pyroscope.scrape "default" {
targets = [
{"__address__" = "localhost:6060"},
]
forward_to = [pyroscope.write.oodle.receiver]
}
pyroscope.write "oodle" {
endpoint {
url = "https://<OODLE_COLLECTOR>/v1/pyroscope/<OODLE_INSTANCE>"
headers = {
"X-API-KEY" = "<OODLE_API_KEY>",
}
}
}