Skip to content

Commit c45879c

Browse files
authored
Add docs on Rust jemalloc profiling (#489)
1 parent 8af945c commit c45879c

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed

docs/parca-agent-language-support.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ All AOT compiled languages with [debug info](./symbolization#what-can-be-symboli
1111
- [C++](https://github.com/parca-dev/parca-demo/tree/main/cpp)
1212
- [Go](https://github.com/parca-dev/parca-demo/tree/main/go) (with [extended support](./symbolization#go))
1313
- [Rust](https://github.com/parca-dev/parca-demo/tree/main/rust)
14+
- [Rust heap usage](/docs/rust-jemalloc-support)
1415
- And more
1516

1617
## Just-in-time (JIT) compilation

docs/rust-jemalloc-support.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Profiling Rust Memory Usage with Jemalloc
2+
3+
Our jemalloc integration makes it possible to profile heap usage of
4+
Rust programs, as long as you are willing to use the jemalloc
5+
allocator.
6+
7+
# Setup Instructions
8+
9+
## Using jemalloc and rust-jemalloc-pprof
10+
11+
Add the
12+
[jemalloc_pprof](https://crates.io/crates/jemalloc-pprof)
13+
and [tikv-jemallocator](https://crates.io/crates/tikv-jemallocator)
14+
packages to your project. Make sure the latter has the `profiling` and
15+
`unprefixed_malloc_on_supported_platforms` features:
16+
17+
``` bash
18+
cargo add jemalloc_pprof
19+
cargo add tikv-jemallocator --features profiling,unprefixed_malloc_on_supported_platforms
20+
```
21+
22+
Then, in your program's `main.rs` set your global allocator to
23+
jemalloc and configure it with the special `malloc_conf` symbol:
24+
25+
``` rust
26+
#[global_allocator]
27+
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
28+
29+
#[unsafe(export_name = "malloc_conf")]
30+
#[allow(non_upper_case_globals)]
31+
pub static malloc_conf: &[u8] = b"prof:true,prof_active:true,lg_prof_sample:19\0";
32+
```
33+
34+
## Exposing pprof profiles with http:
35+
36+
Call the `dump_pprof` method to dump profiles to memory. We
37+
recommending exposing an HTTP interface for these profiles that can be
38+
scraped by Parca.
39+
40+
Here is how to do so using Axum:
41+
42+
``` rust
43+
async fn handle_get_heap() -> Result<impl IntoResponse, (StatusCode, String)> {
44+
let mut prof_ctl = jemalloc_pprof::PROF_CTL
45+
.as_ref()
46+
.ok_or((
47+
StatusCode::INTERNAL_SERVER_ERROR,
48+
"Profiling not available".to_string(),
49+
))?
50+
.lock()
51+
.await;
52+
53+
let pprof = prof_ctl
54+
.dump_pprof()
55+
.map_err(|err| (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()))?;
56+
57+
Ok(pprof)
58+
}
59+
60+
fn main() {
61+
let app = Router::new().route("/debug/pprof/heap", get(handle_get_heap));
62+
63+
let rt = Runtime::new().unwrap();
64+
65+
rt.spawn(async {
66+
let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
67+
.await
68+
.expect("Failed to bind to port 3000");
69+
axum::serve(listener, app).await.expect("Server failed");
70+
});
71+
}
72+
73+
```
74+
75+
## Uploading symbols with `parca-debuginfo` (only if not using
76+
`parca-agent`).
77+
78+
If you are already using `parca-agent`, all relevant symbols will be
79+
found and uploaded to the backend automatically. Otherwise, you will
80+
need to manually upload them using the `parca-debuginfo` CLI. For example,
81+
assuming Parca is running on localhost:
82+
83+
``` bash
84+
parca-debuginfo upload --store-address=localhost:7070 --insecure path/to/your/binary
85+
```
86+
87+
## Scraping with Parca
88+
89+
In order to continually scrape the endpoint, add a stanza like the
90+
following to your `parca.yaml`, assuming (as in the example above) the
91+
profiles are being served via HTTP on `127.0.0.1:3000`:
92+
93+
``` yaml
94+
scrape_configs:
95+
- job_name: "rjemp"
96+
scrape_interval: "10s"
97+
static_configs:
98+
- targets: [ '127.0.0.1:3000' ]
99+
profiling_config:
100+
pprof_config:
101+
heap:
102+
enabled: true
103+
path: /debug/pprof/heap
104+
```
105+
106+
This should cause profiles to appear in the Parca UI.

sidebars.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ module.exports = {
8484
type: "category",
8585
label: "Language Support",
8686
link: { type: "doc", id: "parca-agent-language-support" },
87-
items: ["java-support"],
87+
items: ["java-support", "rust-jemalloc-support"],
8888
},
8989
"parca-agent-security",
9090
],

wordlist.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ addr
55
agentpath
66
ainur
77
Akkoyun
8+
ALLOC
9+
allocator
810
amd
911
Andrii
1012
annotationpresent
@@ -54,6 +56,7 @@ CodeQL
5456
CodeReady
5557
colima
5658
Colima
59+
conf
5760
config
5861
ConfigPath
5962
configs
@@ -69,6 +72,8 @@ cpu
6972
cpuflamegraphs
7073
CRI
7174
cri
75+
ctl
76+
CTL
7277
datacenter
7378
Datasource
7479
datasource
@@ -120,6 +125,7 @@ filesystem
120125
flamegraph
121126
FlameGraphs
122127
flamegraphs
128+
fn
123129
frontend
124130
FrostDB
125131
fs
@@ -129,6 +135,7 @@ ghrc
129135
github
130136
githubusercontent
131137
GitLab
138+
globals
132139
googlegroups
133140
goroutine
134141
Goroutines
@@ -157,6 +164,9 @@ ip
157164
iterateLong
158165
iterateShort
159166
Jaeger
167+
Jemalloc
168+
jemalloc
169+
jemallocator
160170
JIT
161171
jit
162172
jitdump
@@ -201,6 +211,7 @@ lxc
201211
mainc
202212
MAINPID
203213
maintainership
214+
malloc
204215
Manoj
205216
matcher
206217
matchers
@@ -213,6 +224,7 @@ Metastore
213224
metastore
214225
minikube
215226
msg
227+
mut
216228
Mutex
217229
mutex
218230
mynode
@@ -235,6 +247,7 @@ oidc
235247
OpenShift
236248
openshift
237249
OpenTelemetry
250+
ok
238251
otlp
239252
parallelizing
240253
params
@@ -320,6 +333,7 @@ stacktrace
320333
stacktraces
321334
StandardError
322335
StandardOutput
336+
StatusCode
323337
stmt
324338
strp
325339
submodule
@@ -342,6 +356,7 @@ TBD
342356
testdata
343357
Thakkar
344358
Thanos
359+
tikv
345360
TLS
346361
tls
347362
tmp

0 commit comments

Comments
 (0)