Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude profiler #74

Merged
merged 9 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,9 @@ struct Cli {
help = "Derived from constant MAX_PROCESSES"
)]
mapsize_rate_limits: u32,
// Exclude myself from profiling
#[arg(long, help = "Do not profile the profiler (myself)")]
exclude_self: bool,
}

/// Exit the main thread if any thread panics. We prefer this behaviour because pretty much every
Expand Down Expand Up @@ -308,6 +311,7 @@ fn main() -> Result<(), Box<dyn Error>> {
mapsize_unwind_info_chunks: args.mapsize_unwind_info_chunks,
mapsize_unwind_tables: args.mapsize_unwind_tables,
mapsize_rate_limits: args.mapsize_rate_limits,
exclude_self: args.exclude_self,
};

let (stop_signal_sender, stop_signal_receive) = bounded(1);
Expand Down Expand Up @@ -399,8 +403,7 @@ mod tests {
cmd.assert().success();
let actual = String::from_utf8(cmd.unwrap().stdout).unwrap();
insta::assert_yaml_snapshot!(actual, @r###"
---
"Usage: lightswitch [OPTIONS]\n\nOptions:\n --pids <PIDS>\n Specific PIDs to profile\n\n --tids <TIDS>\n Specific TIDs to profile (these can be outside the PIDs selected above)\n\n --show-unwind-info <PATH_TO_BINARY>\n Show unwind info for given binary\n\n --show-info <PATH_TO_BINARY>\n Show build ID for given binary\n\n -D, --duration <DURATION>\n How long this agent will run in seconds\n \n [default: 18446744073709551615]\n\n --libbpf-logs\n Enable libbpf logs. This includes the BPF verifier output\n\n --bpf-logging\n Enable BPF programs logging\n\n --logging <LOGGING>\n Set lightswitch's logging level\n \n [default: info]\n [possible values: trace, debug, info, warn, error]\n\n --sample-freq <SAMPLE_FREQ_IN_HZ>\n Per-CPU Sampling Frequency in Hz\n \n [default: 19]\n\n --profile-format <PROFILE_FORMAT>\n Output file for Flame Graph in SVG format\n \n [default: flame-graph]\n [possible values: none, flame-graph, pprof]\n\n --profile-name <PROFILE_NAME>\n Name for the generated profile\n\n --sender <SENDER>\n Where to write the profile\n \n [default: local-disk]\n\n Possible values:\n - none: Discard the profile. Used for kernel tests\n - local-disk\n - remote\n\n --perf-buffer-bytes <PERF_BUFFER_BYTES>\n Size of each profiler perf buffer, in bytes (must be a power of 2)\n \n [default: 524288]\n\n --mapsize-info\n Print eBPF map sizes after creation\n\n --mapsize-stacks <MAPSIZE_STACKS>\n max number of individual stacks to capture before aggregation\n \n [default: 100000]\n\n --mapsize-aggregated-stacks <MAPSIZE_AGGREGATED_STACKS>\n Derived from constant MAX_AGGREGATED_STACKS_ENTRIES - max number of unique stacks after aggregation\n \n [default: 10000]\n\n --mapsize-unwind-info-chunks <MAPSIZE_UNWIND_INFO_CHUNKS>\n max number of chunks allowed inside a shard\n \n [default: 5000]\n\n --mapsize-unwind-tables <MAPSIZE_UNWIND_TABLES>\n Derived from constant MAX_UNWIND_INFO_SHARDS\n \n [default: 65]\n\n --mapsize-rate-limits <MAPSIZE_RATE_LIMITS>\n Derived from constant MAX_PROCESSES\n \n [default: 5000]\n\n -h, --help\n Print help (see a summary with '-h')\n"
"Usage: lightswitch [OPTIONS]\n\nOptions:\n --pids <PIDS>\n Specific PIDs to profile\n\n --tids <TIDS>\n Specific TIDs to profile (these can be outside the PIDs selected above)\n\n --show-unwind-info <PATH_TO_BINARY>\n Show unwind info for given binary\n\n --show-info <PATH_TO_BINARY>\n Show build ID for given binary\n\n -D, --duration <DURATION>\n How long this agent will run in seconds\n \n [default: 18446744073709551615]\n\n --libbpf-logs\n Enable libbpf logs. This includes the BPF verifier output\n\n --bpf-logging\n Enable BPF programs logging\n\n --logging <LOGGING>\n Set lightswitch's logging level\n \n [default: info]\n [possible values: trace, debug, info, warn, error]\n\n --sample-freq <SAMPLE_FREQ_IN_HZ>\n Per-CPU Sampling Frequency in Hz\n \n [default: 19]\n\n --profile-format <PROFILE_FORMAT>\n Output file for Flame Graph in SVG format\n \n [default: flame-graph]\n [possible values: none, flame-graph, pprof]\n\n --profile-name <PROFILE_NAME>\n Name for the generated profile\n\n --sender <SENDER>\n Where to write the profile\n \n [default: local-disk]\n\n Possible values:\n - none: Discard the profile. Used for kernel tests\n - local-disk\n - remote\n\n --perf-buffer-bytes <PERF_BUFFER_BYTES>\n Size of each profiler perf buffer, in bytes (must be a power of 2)\n \n [default: 524288]\n\n --mapsize-info\n Print eBPF map sizes after creation\n\n --mapsize-stacks <MAPSIZE_STACKS>\n max number of individual stacks to capture before aggregation\n \n [default: 100000]\n\n --mapsize-aggregated-stacks <MAPSIZE_AGGREGATED_STACKS>\n Derived from constant MAX_AGGREGATED_STACKS_ENTRIES - max number of unique stacks after aggregation\n \n [default: 10000]\n\n --mapsize-unwind-info-chunks <MAPSIZE_UNWIND_INFO_CHUNKS>\n max number of chunks allowed inside a shard\n \n [default: 5000]\n\n --mapsize-unwind-tables <MAPSIZE_UNWIND_TABLES>\n Derived from constant MAX_UNWIND_INFO_SHARDS\n \n [default: 65]\n\n --mapsize-rate-limits <MAPSIZE_RATE_LIMITS>\n Derived from constant MAX_PROCESSES\n \n [default: 5000]\n\n --exclude-self\n Do not profile the profiler (myself)\n\n -h, --help\n Print help (see a summary with '-h')\n"
"###);
}

Expand Down
10 changes: 10 additions & 0 deletions src/profiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ pub struct Profiler<'bpf> {
// Size of each perf buffer, in bytes
perf_buffer_bytes: usize,
session_duration: Duration,
// Whether the profiler (this process) should be excluded from profiling
exclude_self: bool,
}

// Static config
Expand Down Expand Up @@ -326,6 +328,7 @@ pub struct ProfilerConfig {
pub mapsize_unwind_info_chunks: u32,
pub mapsize_unwind_tables: u32,
pub mapsize_rate_limits: u32,
pub exclude_self: bool,
}

// Note that we normally pass in the defaults from Clap, and we don't want
Expand All @@ -346,6 +349,7 @@ impl Default for ProfilerConfig {
mapsize_unwind_info_chunks: 5000,
mapsize_unwind_tables: 65,
mapsize_rate_limits: 5000,
exclude_self: false,
}
}
}
Expand Down Expand Up @@ -398,6 +402,7 @@ impl Profiler<'_> {
.lightswitch_config
.verbose_logging
.write(profiler_config.bpf_logging);
let exclude_self = profiler_config.exclude_self;
gmarler marked this conversation as resolved.
Show resolved Hide resolved
let bpf = open_skel.load().expect("load skel");
info!("native unwinder BPF program loaded");
let native_unwinder_maps = bpf.maps();
Expand Down Expand Up @@ -491,6 +496,7 @@ impl Profiler<'_> {
sample_freq,
perf_buffer_bytes,
session_duration: Duration::from_secs(5),
exclude_self,
}
}

Expand Down Expand Up @@ -1216,6 +1222,10 @@ impl Profiler<'_> {
}

fn should_profile(&self, pid: i32) -> bool {
if self.exclude_self && (pid == std::process::id().try_into().unwrap()) {
gmarler marked this conversation as resolved.
Show resolved Hide resolved
return false;
}

if self.filter_pids.is_empty() {
return true;
}
Expand Down