Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Profiling Rust services with pprof
This package aims to help Rust workspace services with an Axum web server create CPU and heap profile snapshots and visualizations that you can download and interact with on your local machine.
The core output format and tooling for all of the above is pprof. Most of the reference material and usage for pprof is Golang oriented, but translates pretty naturally to the Rust environment.
Setup
Local machine setup
- Install a recent version of Golang (this will include the core
pproftool) - Install related local dependencies for desired visualization features (
graphviz,dotetc.) - Install
kubectland ensure AWS credentials/SSO are configured to use it against our production k8s clusters
Service setup
This library can be integrated into your Rust workspace project in a couple steps:
- Add the
common/profilerdependency to your service. Replacecommon/allocdependency if present - Add the
used_with_profiling!()macro to yourmain.rs, or replacecommon/alloc'sused!()invocation - example here as defined here - Add the profiling trigger endpoints to your Axum server's
Router- example here as defined here
...and that's about it! Deploy your service and use the instructions below to get started
Using pprof in production
Obtaining a profile snapshot
Set up k8s port forwarding on your local machine from your service's load balancer or a particular pod. Note this is a blocking operation - you can background it, or leave it running in foreground and start a new session for next steps.
# Set local k8s env (posthog-prod, posthog-prod-eu, dev)
$ kubectl config use-context posthog-prod-eu
# Notes:
# - You can also use "pod/kafka-deduplicator-2" (pod name) to select a specific pod
# - Ensure you forward the HTTP port that your Axum server exposes in k8s
$ kubectl port-forward --namespace posthog service/kafka-deduplicator 8000:8000
curl the pprof endpoint and pipe the resulting GZIP'd output to your local filesystem.
# Capture CPU profile report as GZIP'd protobuf file. Optional URL query params:
# seconds=N | How long the sampling profiler should run before returning the report (default 10)
# frequency=N | Sampling frequency for profile report (default 200)
#
# Note: The defaults are a good place to start. Ensure "seconds" param doesn't exceed the request timeout!
$ curl -sSL -H 'Connection: keep-alive' -H 'Keep-Alive: timeout=60,max=100' 'http://localhost:8000/pprof/profile/report' > profile.pb.gz
# Obtain a heap allocation profile
$ curl -sSL -H 'Connection: keep-alive' -H 'Keep-Alive: timeout=60,max=100' 'http://localhost:8000/pprof/heap/report' > heap.pb.gz
# Corresponding profile and heap flamegraph endpoints return pre-generated SVG images of configurable size
Introspect on the profile reports you've pulled down
# Unzip the report protobuf
$ unzip profile.pb.gz
# Use pprof tool to introspect on report. Basic syntax:
$ go tool pprof <options> <optional_path_to_local_debug_binary> <path_to_profile_report_file>
# Examples:
# Open interactive web interface to analyze report (recommended)
$ go tool pprof -http=localhost:<PORT> profile.pb
# Open interactive CLI shell with report
$ go tool pprof profile.pb
# Include service binary for additional symbol translation (YMMV, can add this arg to any of the commands listed here)
$ go tool pprof posthog/rust/target/debug/kafka-deduplicator profile.pb
# Open web browser with SVG image of profile report
$ go tool pprof -web profile.pb
# Generate and open a local PNG image of the profile report
$ go tool pprof -png profile.pb && open profile001.png
# Quick summary report
$ go tool pprof -top profile.pb
Additional introspect options and context on pprof is available online: