Skip to content

Commit 10cd7e9

Browse files
committed
feat(profiler): Add profiling instructions
1 parent d8265ad commit 10cd7e9

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

contrib/PROFILING.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Profiling Tools
2+
3+
This document explains the profiling infrastructure set up for our indexer-service and tap-agent services. The profiling setup enables developers to diagnose performance issues, memory leaks, and analyze runtime behavior in both development and production environments.
4+
5+
## Overview
6+
7+
Our project includes an integrated profiling system for the indexer services. The system supports multiple profiling methods through:
8+
9+
1. A custom `profiler` library (included in the workspace)
10+
2. Docker-based profiling environments
11+
3. Various third-party profiling tools
12+
13+
## Available Profiling Methods
14+
15+
### Built-in Profiler (pprof-based Flamegraphs)
16+
17+
A Rust library that uses [pprof](https://crates.io/crates/pprof) to continuously profile the application and generate flamegraphs at specified intervals.
18+
This solution was particularly suitable because tools like `perf`, while powerful, often pose configuration challenges or require specific capabilities (like CAP_SYS_ADMIN) that complicate their deployment within standard Docker containers.
19+
20+
- **Configuration**: Set in code with the `setup_profiling` function
21+
- **Activation**: Enabled via the `profiling` feature flag
22+
- **Output**: Flamegraphs (SVG) and protobuf profiles in `/opt/profiling/{service-name}/`
23+
24+
### External Profiling Tools
25+
26+
The profiling environment also supports the following tools:
27+
28+
| Tool | Description | Output |
29+
| ------------- | ---------------------------------------- | --------------------------------------------- |
30+
| **strace** | Traces system calls with detailed timing | `/opt/profiling/{service-name}/strace.log` |
31+
| **valgrind** | Memory profiling with Massif | `/opt/profiling/{service-name}/massif.out` |
32+
| **callgrind** | CPU profiling (part of valgrind) | `/opt/profiling/{service-name}/callgrind.out` |
33+
34+
## How to Use
35+
36+
### Prerequisites
37+
38+
Run the setup command first to prepare the testing environment:
39+
40+
```bash
41+
just setup
42+
```
43+
44+
### Profiling Commands
45+
46+
Use the following commands to profile specific services:
47+
48+
```bash
49+
# Profile with flamegraph (default)
50+
just profile-flamegraph
51+
52+
# Profile with valgrind
53+
just profile-valgrind
54+
55+
# Profile with strace
56+
just profile-strace
57+
58+
# Profile with callgrind
59+
just profile-callgrind
60+
61+
# Stop profiling (gracefully terminate to generate output)
62+
just stop-profiling
63+
64+
# Restore normal service without profiling
65+
just profile-restore
66+
```
67+
68+
### Viewing Results
69+
70+
Profiling data is stored in:
71+
72+
- `contrib/profiling/indexer-service/`
73+
- `contrib/profiling/tap-agent/`
74+
75+
#### Visualization Tools
76+
77+
- **Flamegraphs**: Open the SVG files in any web browser
78+
- **Callgrind**: Use `callgrind_annotate` or KCachegrind for visualization:
79+
80+
```bash
81+
callgrind_annotate contrib/profiling/tap-agent/callgrind.out
82+
```
83+
84+
- **Massif**: Use `ms_print` to view memory profiling results:
85+
86+
```bash
87+
ms_print contrib/profiling/tap-agent/massif.out
88+
```
89+
90+
- **Protobuf Profiles**: View with Go pprof tools:
91+
92+
```go
93+
# Install Go pprof tools if needed
94+
go install github.com/google/pprof@latest
95+
96+
# View interactive web UI (most user-friendly)
97+
pprof -http=:8080 contrib/profiling/indexer-service/profile-*.pb
98+
99+
# Or generate a flamegraph from protobuf data
100+
pprof -flamegraph contrib/profiling/indexer-service/profile-*.pb > custom_flamegraph.svg
101+
```
102+
103+
## Implementation Details
104+
105+
### Profiler Integration
106+
107+
The profiler library is conditionally compiled using the `profiling` feature flag:
108+
109+
```rust
110+
#[cfg(feature = "profiling")]
111+
if let Err(e) = profiler::setup_profiling(
112+
"/opt/profiling/indexer-service".to_string(),
113+
150, // sampling frequency (Hz)
114+
120, // interval between reports (seconds)
115+
Some("Indexer Service".to_string()),
116+
) {
117+
tracing::error!("Failed to setup profiling: {e}");
118+
} else {
119+
tracing::info!("Profiling setup complete.");
120+
}
121+
```
122+
123+
### Docker Environment
124+
125+
The profiling infrastructure uses a custom Docker image with all necessary tools pre-installed. The container runs with elevated privileges to support profiling:
126+
127+
```yaml
128+
cap_add:
129+
- SYS_ADMIN
130+
privileged: true
131+
security_opt:
132+
- seccomp:unconfined
133+
```
134+
135+
## Notes
136+
137+
- The flamegraph profiling is enabled whenever using any of the profiling commands through the Justfile, as the binaries are compiled with the `profiling` feature flag.
138+
- For production use, prefer the built-in profiler over the external tools to minimize performance impact.
139+
- When using callgrind, consider enabling debug information and frame pointers in your Cargo.toml for better output:
140+
141+
```toml
142+
[profile.release]
143+
debug = true
144+
force-frame-pointers = true
145+
```

0 commit comments

Comments
 (0)