Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/parca-agent-language-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All AOT compiled languages with [debug info](./symbolization#what-can-be-symboli
- [C++](https://github.com/parca-dev/parca-demo/tree/main/cpp)
- [Go](https://github.com/parca-dev/parca-demo/tree/main/go) (with [extended support](./symbolization#go))
- [Rust](https://github.com/parca-dev/parca-demo/tree/main/rust)
- [Rust heap usage](/docs/rust-jemalloc-support)
- And more

## Just-in-time (JIT) compilation
Expand Down
106 changes: 106 additions & 0 deletions docs/rust-jemalloc-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Profiling Rust Memory Usage with Jemalloc

Our jemalloc integration makes it possible to profile heap usage of
Rust programs, as long as you are willing to use the jemalloc
allocator.

# Setup Instructions

## Using jemalloc and rust-jemalloc-pprof

Add the
[jemalloc_pprof](https://crates.io/crates/jemalloc-pprof)
and [tikv-jemallocator](https://crates.io/crates/tikv-jemallocator)
packages to your project. Make sure the latter has the `profiling` and
`unprefixed_malloc_on_supported_platforms` features:

``` bash
cargo add jemalloc_pprof
cargo add tikv-jemallocator --features profiling,unprefixed_malloc_on_supported_platforms
```

Then, in your program's `main.rs` set your global allocator to
jemalloc and configure it with the special `malloc_conf` symbol:

``` rust
#[global_allocator]
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;

#[unsafe(export_name = "malloc_conf")]
#[allow(non_upper_case_globals)]
pub static malloc_conf: &[u8] = b"prof:true,prof_active:true,lg_prof_sample:19\0";
```

## Exposing pprof profiles with http:

Call the `dump_pprof` method to dump profiles to memory. We
recommending exposing an HTTP interface for these profiles that can be
scraped by Parca.

Here is how to do so using Axum:

``` rust
async fn handle_get_heap() -> Result<impl IntoResponse, (StatusCode, String)> {
let mut prof_ctl = jemalloc_pprof::PROF_CTL
.as_ref()
.ok_or((
StatusCode::INTERNAL_SERVER_ERROR,
"Profiling not available".to_string(),
))?
.lock()
.await;

let pprof = prof_ctl
.dump_pprof()
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()))?;

Ok(pprof)
}

fn main() {
let app = Router::new().route("/debug/pprof/heap", get(handle_get_heap));

let rt = Runtime::new().unwrap();

rt.spawn(async {
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
.await
.expect("Failed to bind to port 3000");
axum::serve(listener, app).await.expect("Server failed");
});
}

```

## Uploading symbols with `parca-debuginfo` (only if not using
`parca-agent`).

If you are already using `parca-agent`, all relevant symbols will be
found and uploaded to the backend automatically. Otherwise, you will
need to manually upload them using the `parca-debuginfo` CLI. For example,
assuming Parca is running on localhost:

``` bash
parca-debuginfo upload --store-address=localhost:7070 --insecure path/to/your/binary
```

## Scraping with Parca

In order to continually scrape the endpoint, add a stanza like the
following to your `parca.yaml`, assuming (as in the example above) the
profiles are being served via HTTP on `127.0.0.1:3000`:

``` yaml
scrape_configs:
- job_name: "rjemp"
scrape_interval: "10s"
static_configs:
- targets: [ '127.0.0.1:3000' ]
profiling_config:
pprof_config:
heap:
enabled: true
path: /debug/pprof/heap
```

This should cause profiles to appear in the Parca UI.
2 changes: 1 addition & 1 deletion sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ module.exports = {
type: "category",
label: "Language Support",
link: { type: "doc", id: "parca-agent-language-support" },
items: ["java-support"],
items: ["java-support", "rust-jemalloc-support"],
},
"parca-agent-security",
],
Expand Down
15 changes: 15 additions & 0 deletions wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ addr
agentpath
ainur
Akkoyun
ALLOC
allocator
amd
Andrii
annotationpresent
Expand Down Expand Up @@ -54,6 +56,7 @@ CodeQL
CodeReady
colima
Colima
conf
config
ConfigPath
configs
Expand All @@ -69,6 +72,8 @@ cpu
cpuflamegraphs
CRI
cri
ctl
CTL
datacenter
Datasource
datasource
Expand Down Expand Up @@ -120,6 +125,7 @@ filesystem
flamegraph
FlameGraphs
flamegraphs
fn
frontend
FrostDB
fs
Expand All @@ -129,6 +135,7 @@ ghrc
github
githubusercontent
GitLab
globals
googlegroups
goroutine
Goroutines
Expand Down Expand Up @@ -157,6 +164,9 @@ ip
iterateLong
iterateShort
Jaeger
Jemalloc
jemalloc
jemallocator
JIT
jit
jitdump
Expand Down Expand Up @@ -201,6 +211,7 @@ lxc
mainc
MAINPID
maintainership
malloc
Manoj
matcher
matchers
Expand All @@ -213,6 +224,7 @@ Metastore
metastore
minikube
msg
mut
Mutex
mutex
mynode
Expand All @@ -235,6 +247,7 @@ oidc
OpenShift
openshift
OpenTelemetry
ok
otlp
parallelizing
params
Expand Down Expand Up @@ -320,6 +333,7 @@ stacktrace
stacktraces
StandardError
StandardOutput
StatusCode
stmt
strp
submodule
Expand All @@ -342,6 +356,7 @@ TBD
testdata
Thakkar
Thanos
tikv
TLS
tls
tmp
Expand Down