mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-13 08:22:55 +00:00
## Problem We don't have a convenient way to gather CPU profiles from a running binary, e.g. during production incidents or end-to-end benchmarks, nor during microbenchmarks (particularly on macOS). We would also like to have continuous profiling in production, likely using [Grafana Cloud Profiles](https://grafana.com/products/cloud/profiles-for-continuous-profiling/). We may choose to use either eBPF profiles or pprof profiles for this (pending testing and discussion with SREs), but pprof profiles appear useful regardless for the reasons listed above. See https://github.com/neondatabase/cloud/issues/14888. This PR is intended as a proof of concept, to try it out in staging and drive further discussions about profiling more broadly. Touches #9534. Touches https://github.com/neondatabase/cloud/issues/14888. ## Summary of changes Adds a HTTP route `/profile/cpu` that takes a CPU profile and returns it. Defaults to a 5-second pprof Protobuf profile for use with e.g. `pprof` or Grafana Alloy, but can also emit an SVG flamegraph. Query parameters: * `format`: output format (`pprof` or `svg`) * `frequency`: sampling frequency in microseconds (default 100) * `seconds`: number of seconds to profile (default 5) Also integrates pprof profiles into Criterion benchmarks, such that flamegraph reports can be taken with `cargo bench ... --profile-duration <seconds>`. Output under `target/criterion/*/profile/flamegraph.svg`. Example profiles: * pprof profile (use [`pprof`](https://github.com/google/pprof)): [profile.pb.gz](https://github.com/user-attachments/files/17756788/profile.pb.gz) * Web interface: `pprof -http :6060 profile.pb.gz` * Interactive flamegraph: [profile.svg.gz](https://github.com/user-attachments/files/17756782/profile.svg.gz)
137 lines
8.2 KiB
TOML
137 lines
8.2 KiB
TOML
# This file is generated by `cargo hakari`.
|
|
# To regenerate, run:
|
|
# cargo hakari generate
|
|
|
|
[package]
|
|
name = "workspace_hack"
|
|
version = "0.1.0"
|
|
description = "workspace-hack package, managed by hakari"
|
|
# You can choose to publish this crate: see https://docs.rs/cargo-hakari/latest/cargo_hakari/publishing.
|
|
publish = false
|
|
edition.workspace = true
|
|
license.workspace = true
|
|
# The parts of the file between the BEGIN HAKARI SECTION and END HAKARI SECTION comments
|
|
# are managed by hakari.
|
|
|
|
### BEGIN HAKARI SECTION
|
|
[dependencies]
|
|
ahash = { version = "0.8" }
|
|
anyhow = { version = "1", features = ["backtrace"] }
|
|
axum = { version = "0.7", features = ["ws"] }
|
|
axum-core = { version = "0.4", default-features = false, features = ["tracing"] }
|
|
base64 = { version = "0.21", features = ["alloc"] }
|
|
base64ct = { version = "1", default-features = false, features = ["std"] }
|
|
bytes = { version = "1", features = ["serde"] }
|
|
camino = { version = "1", default-features = false, features = ["serde1"] }
|
|
chrono = { version = "0.4", default-features = false, features = ["clock", "serde", "wasmbind"] }
|
|
clap = { version = "4", features = ["derive", "env", "string"] }
|
|
clap_builder = { version = "4", default-features = false, features = ["color", "env", "help", "std", "string", "suggestions", "usage"] }
|
|
crypto-bigint = { version = "0.5", features = ["generic-array", "zeroize"] }
|
|
der = { version = "0.7", default-features = false, features = ["oid", "pem", "std"] }
|
|
deranged = { version = "0.3", default-features = false, features = ["powerfmt", "serde", "std"] }
|
|
digest = { version = "0.10", features = ["mac", "oid", "std"] }
|
|
either = { version = "1" }
|
|
fail = { version = "0.5", default-features = false, features = ["failpoints"] }
|
|
futures-channel = { version = "0.3", features = ["sink"] }
|
|
futures-executor = { version = "0.3" }
|
|
futures-io = { version = "0.3" }
|
|
futures-util = { version = "0.3", features = ["channel", "io", "sink"] }
|
|
generic-array = { version = "0.14", default-features = false, features = ["more_lengths", "zeroize"] }
|
|
getrandom = { version = "0.2", default-features = false, features = ["std"] }
|
|
half = { version = "2", default-features = false, features = ["num-traits"] }
|
|
hashbrown = { version = "0.14", features = ["raw"] }
|
|
hex = { version = "0.4", features = ["serde"] }
|
|
hmac = { version = "0.12", default-features = false, features = ["reset"] }
|
|
hyper-582f2526e08bb6a0 = { package = "hyper", version = "0.14", features = ["full"] }
|
|
hyper-dff4ba8e3ae991db = { package = "hyper", version = "1", features = ["full"] }
|
|
hyper-util = { version = "0.1", features = ["client-legacy", "server-auto", "service"] }
|
|
indexmap-dff4ba8e3ae991db = { package = "indexmap", version = "1", default-features = false, features = ["std"] }
|
|
indexmap-f595c2ba2a3f28df = { package = "indexmap", version = "2", features = ["serde"] }
|
|
itertools = { version = "0.12" }
|
|
lazy_static = { version = "1", default-features = false, features = ["spin_no_std"] }
|
|
libc = { version = "0.2", features = ["extra_traits", "use_std"] }
|
|
log = { version = "0.4", default-features = false, features = ["std"] }
|
|
memchr = { version = "2" }
|
|
nix = { version = "0.26" }
|
|
nom = { version = "7" }
|
|
num-bigint = { version = "0.4" }
|
|
num-integer = { version = "0.1", features = ["i128"] }
|
|
num-traits = { version = "0.2", features = ["i128", "libm"] }
|
|
once_cell = { version = "1" }
|
|
parquet = { version = "53", default-features = false, features = ["zstd"] }
|
|
postgres-types = { git = "https://github.com/neondatabase/rust-postgres.git", branch = "neon", default-features = false, features = ["with-serde_json-1"] }
|
|
prost = { version = "0.13", features = ["prost-derive"] }
|
|
rand = { version = "0.8", features = ["small_rng"] }
|
|
regex = { version = "1" }
|
|
regex-automata = { version = "0.4", default-features = false, features = ["dfa-onepass", "hybrid", "meta", "nfa-backtrack", "perf-inline", "perf-literal", "unicode"] }
|
|
regex-syntax = { version = "0.8" }
|
|
reqwest = { version = "0.12", default-features = false, features = ["blocking", "json", "rustls-tls", "rustls-tls-native-roots", "stream"] }
|
|
rustls = { version = "0.23", default-features = false, features = ["logging", "ring", "std", "tls12"] }
|
|
scopeguard = { version = "1" }
|
|
serde = { version = "1", features = ["alloc", "derive"] }
|
|
serde_json = { version = "1", features = ["alloc", "raw_value"] }
|
|
sha2 = { version = "0.10", features = ["asm", "oid"] }
|
|
signature = { version = "2", default-features = false, features = ["digest", "rand_core", "std"] }
|
|
smallvec = { version = "1", default-features = false, features = ["const_new", "write"] }
|
|
spki = { version = "0.7", default-features = false, features = ["pem", "std"] }
|
|
subtle = { version = "2" }
|
|
sync_wrapper = { version = "0.1", default-features = false, features = ["futures"] }
|
|
tikv-jemalloc-sys = { version = "0.6", features = ["stats"] }
|
|
time = { version = "0.3", features = ["macros", "serde-well-known"] }
|
|
tokio = { version = "1", features = ["fs", "io-std", "io-util", "macros", "net", "process", "rt-multi-thread", "signal", "test-util"] }
|
|
tokio-postgres = { git = "https://github.com/neondatabase/rust-postgres.git", branch = "neon", features = ["with-serde_json-1"] }
|
|
tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring", "tls12"] }
|
|
tokio-stream = { version = "0.1", features = ["net"] }
|
|
tokio-util = { version = "0.7", features = ["codec", "compat", "io", "rt"] }
|
|
toml_edit = { version = "0.22", features = ["serde"] }
|
|
tonic = { version = "0.12", features = ["tls-roots"] }
|
|
tower = { version = "0.4", default-features = false, features = ["balance", "buffer", "limit", "log", "util"] }
|
|
tracing = { version = "0.1", features = ["log"] }
|
|
tracing-core = { version = "0.1" }
|
|
url = { version = "2", features = ["serde"] }
|
|
zerocopy = { version = "0.7", features = ["derive", "simd"] }
|
|
zeroize = { version = "1", features = ["derive", "serde"] }
|
|
zstd = { version = "0.13" }
|
|
zstd-safe = { version = "7", default-features = false, features = ["arrays", "legacy", "std", "zdict_builder"] }
|
|
zstd-sys = { version = "2", default-features = false, features = ["legacy", "std", "zdict_builder"] }
|
|
|
|
[build-dependencies]
|
|
ahash = { version = "0.8" }
|
|
anyhow = { version = "1", features = ["backtrace"] }
|
|
bytes = { version = "1", features = ["serde"] }
|
|
cc = { version = "1", default-features = false, features = ["parallel"] }
|
|
chrono = { version = "0.4", default-features = false, features = ["clock", "serde", "wasmbind"] }
|
|
either = { version = "1" }
|
|
getrandom = { version = "0.2", default-features = false, features = ["std"] }
|
|
half = { version = "2", default-features = false, features = ["num-traits"] }
|
|
hashbrown = { version = "0.14", features = ["raw"] }
|
|
indexmap-dff4ba8e3ae991db = { package = "indexmap", version = "1", default-features = false, features = ["std"] }
|
|
indexmap-f595c2ba2a3f28df = { package = "indexmap", version = "2", features = ["serde"] }
|
|
itertools = { version = "0.12" }
|
|
libc = { version = "0.2", features = ["extra_traits", "use_std"] }
|
|
log = { version = "0.4", default-features = false, features = ["std"] }
|
|
memchr = { version = "2" }
|
|
nom = { version = "7" }
|
|
num-bigint = { version = "0.4" }
|
|
num-integer = { version = "0.1", features = ["i128"] }
|
|
num-traits = { version = "0.2", features = ["i128", "libm"] }
|
|
once_cell = { version = "1" }
|
|
parquet = { version = "53", default-features = false, features = ["zstd"] }
|
|
prettyplease = { version = "0.2", default-features = false, features = ["verbatim"] }
|
|
proc-macro2 = { version = "1" }
|
|
prost = { version = "0.13", features = ["prost-derive"] }
|
|
quote = { version = "1" }
|
|
regex = { version = "1" }
|
|
regex-automata = { version = "0.4", default-features = false, features = ["dfa-onepass", "hybrid", "meta", "nfa-backtrack", "perf-inline", "perf-literal", "unicode"] }
|
|
regex-syntax = { version = "0.8" }
|
|
serde = { version = "1", features = ["alloc", "derive"] }
|
|
syn = { version = "2", features = ["extra-traits", "fold", "full", "visit", "visit-mut"] }
|
|
time-macros = { version = "0.2", default-features = false, features = ["formatting", "parsing", "serde"] }
|
|
toml_edit = { version = "0.22", features = ["serde"] }
|
|
zerocopy = { version = "0.7", features = ["derive", "simd"] }
|
|
zstd = { version = "0.13" }
|
|
zstd-safe = { version = "7", default-features = false, features = ["arrays", "legacy", "std", "zdict_builder"] }
|
|
zstd-sys = { version = "2", default-features = false, features = ["legacy", "std", "zdict_builder"] }
|
|
|
|
### END HAKARI SECTION
|