|
| 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