pub struct Builder<'a> { /* private fields */ }
Expand description
A builder for Counter
s.
There are dozens of parameters that influence a Counter
’s behavior.
Builder
lets you construct a Counter
by specifying only those parameters
for which you don’t want the default value.
A freshly built Counter
is disabled. To begin counting events, you must
call enable
on the Counter
or the Group
to which it belongs.
For example, if you want a Counter
for instructions retired by the current
process, those are Builder
’s defaults, so you need only write:
let mut insns = Builder::new(Hardware::INSTRUCTIONS).build()?;
If you would like to gather individual counters into a Group
you can
use the Group::add
method. A Group
allows you to enable or disable
all the grouped counters atomically.
let mut group = Group::new()?;
let cycles = group.add(&Builder::new(Hardware::CPU_CYCLES))?;
let insns = group.add(&Builder::new(Hardware::INSTRUCTIONS))?;
Other methods let you select:
- specific processes or cgroups to observe
- specific CPU cores to observe
Builder
supports only a fraction of the many knobs and dials Linux offers,
but hopefully it will acquire methods to support more of them as time goes
on.
Internally, a Builder
is just a wrapper around the kernel’s struct perf_event_attr
type.
Implementations§
Source§impl<'a> Builder<'a>
impl<'a> Builder<'a>
Sourcepub fn new<E: Event>(event: E) -> Self
pub fn new<E: Event>(event: E) -> Self
Return a new Builder
, with all parameters set to their defaults.
Return a new Builder
for the specified event.
Sourcepub fn event<E: Event>(&mut self, event: E) -> &mut Self
pub fn event<E: Event>(&mut self, event: E) -> &mut Self
Override the event configured for this builder.
This can be used reuse other configuration for the builder (which processes/CPUs to observe, sampling fields, read format, etc.) while building counters for different events.
Before configuring the perf_event_attr
struct using the event all
config fields within it will be set to 0. Specifically: type_
,
config
, config1
, config2
, and config3
. This ensures that most
events do not have to worry about resetting state that other events may
have set.
Sourcepub fn build(&self) -> Result<Counter>
pub fn build(&self) -> Result<Counter>
Construct a Counter
according to the specifications made on this
Builder
.
If you want to add this counter to a group use build_with_group
instead.
By default, a newly built Counter
is disabled. To begin counting
events, you must call enable
on the Counter
or the Group
to which it belongs. Alternatively, certain options (e.g.
enable_on_exec
) may be used to automatically enable the Counter
once certain events occur.
§Errors
- The
perf_event_open
syscall has a large number of different errors it can return. See the man page for details. Unfortunately, the errors returned by the kernel are not always helpful. - This method translates
E2BIG
errors (which means the kernel did not support some options) into a customstd::io::Error
with kindErrorKind::Unsupported
and an internal error ofUnsupportedOptionsError
. This allows you to access the size of theperf_event_attr
struct that the kernel was expecting.
§Panics
This method panics if attrs.size
has been set to a value larger than
the size of the perf_event_attr
struct.
Sourcepub fn build_with_group(&self, group: impl AsMut<Counter>) -> Result<Counter>
pub fn build_with_group(&self, group: impl AsMut<Counter>) -> Result<Counter>
Construct a Counter
as part of a group.
The group
passed in must be the leader of the group you to add the
resulting Counter
to.
§Notes
- The group leader does not have to be a
Group
(although it can be), anyCounter
will work just fine as a group leader provided it is not already within a group itself. - Similarly with enabling, disabling, or resetting all counters in the
group. Any counter in the group can do those via
enable_group
,disable_group
, andreset_group
. - The same applies for reading group values. Any counter that has
ReadFormat::GROUP
set inread_format
can read the counter values for the entire group usingread_group
.
Note, however, that Group
is likely to be more convenient if you
don’t want to set ReadFormat::GROUP
on any of the counters
within the group.
§Errors
- The
perf_event_open
syscall has a large number of different errors it can return. See the man page for details. Unfortunately, the errors returned by the kernel are not always helpful. - This method translates
E2BIG
errors (which means the kernel did not support some options) into a customstd::io::Error
with kindErrorKind::Unsupported
and an internal error ofUnsupportedOptionsError
. This allows you to access the size of theperf_event_attr
struct that the kernel was expecting.
§Panics
This method panics if attrs.size
has been set to a value larger than
the size of the perf_event_attr
struct.
Sourcepub fn build_group(&self) -> Result<Group>
pub fn build_group(&self) -> Result<Group>
Build a Group
according to the specifications made on this
Builder
.
Note that you will need to have set ReadFormat::GROUP
within
read_format
to or this method will error.
§Notes
- A
Group
is just a wrapper around aCounter
whose methods use the corresponding*_group
methods onCounter
. - The
GroupData
returned fromGroup::read
doesn’t include the group itself when being iterated over. You will likely want to use theSoftware::DUMMY
event when constructing a group.
§Errors
- All errors that can be returned from
build
. - An error will be returned if
ReadFormat::GROUP
is not set withinread_format
. It will have a kind ofErrorKind::Other
.
§Panics
This method panics if attrs.size
has been set to a value larger than
the size of the perf_event_attr
struct.
Source§impl<'a> Builder<'a>
impl<'a> Builder<'a>
Sourcepub fn attrs(&self) -> &perf_event_attr
pub fn attrs(&self) -> &perf_event_attr
Directly access the perf_event_attr
within this builder.
Sourcepub fn attrs_mut(&mut self) -> &mut perf_event_attr
pub fn attrs_mut(&mut self) -> &mut perf_event_attr
Directly access the perf_event_attr
within this builder.
Sourcepub fn observe_self(&mut self) -> &mut Self
pub fn observe_self(&mut self) -> &mut Self
Observe the calling process. (This is the default.)
Sourcepub fn observe_pid(&mut self, pid: pid_t) -> &mut Self
pub fn observe_pid(&mut self, pid: pid_t) -> &mut Self
Observe the process with the given process id. This requires
CAP_SYS_PTRACE
capabilities.
Sourcepub fn any_pid(&mut self) -> &mut Self
pub fn any_pid(&mut self) -> &mut Self
Observe all processes.
Linux does not support observing all processes on all CPUs without
restriction, so combining any_pid
with any_cpu
will cause the
final build
to return an error. This must be used together with
one_cpu
, to select a specific CPU to observe.
This requires CAP_PERFMON
or CAP_SYS_ADMIN
capabilities, or a /proc/sys/kernel/perf_event_paranoid
value of less
than 1.
Sourcepub fn observe_cgroup(&mut self, cgroup: &'a File) -> &mut Self
pub fn observe_cgroup(&mut self, cgroup: &'a File) -> &mut Self
Observe code running in the given cgroup (container). The
cgroup
argument should be a File
referring to the cgroup’s directory
in the cgroupfs filesystem.
Sourcepub fn one_cpu(&mut self, cpu: usize) -> &mut Self
pub fn one_cpu(&mut self, cpu: usize) -> &mut Self
Observe only code running on the given CPU core.
Sourcepub fn any_cpu(&mut self) -> &mut Self
pub fn any_cpu(&mut self) -> &mut Self
Observe code running on any CPU core. (This is the default.)
Linux does not support observing all processes on all CPUs without
restriction, so combining any_cpu
with any_pid
will cause
build
to return an error. This must be used with observe_self
(the default), observe_pid
, or observe_cgroup
.
Sourcepub fn sample(&mut self, sample: SampleFlag) -> &mut Self
pub fn sample(&mut self, sample: SampleFlag) -> &mut Self
Indicate additional values to include in the generated sample events.
Note that this method is additive and does not remove previously added
sample types. See the documentation of SampleFlag
or the manpage
for what’s available to be collected.
§Example
Here we build a sampler that grabs the instruction pointer, process ID, thread ID, and timestamp whenever the underlying event triggers a sampling.
let mut sampler = Builder::new(Hardware::INSTRUCTIONS)
.sample(SampleFlag::IP)
.sample(SampleFlag::TID)
.sample(SampleFlag::TIME)
.build()?
.sampled(8192)?;
Sourcepub fn read_format(&mut self, read_format: ReadFormat) -> &mut Self
pub fn read_format(&mut self, read_format: ReadFormat) -> &mut Self
Set the fields to include when reading from the counter.
Note that this method is not additive, unlike sample
.
The implementation of this library will silently mask out certain flags
if they would be invalid. For example, we will not allow you to set
ReadFormat::GROUP
when building a single counter.
Source§impl<'a> Builder<'a>
impl<'a> Builder<'a>
Sourcepub fn enabled(&mut self, enabled: bool) -> &mut Self
pub fn enabled(&mut self, enabled: bool) -> &mut Self
Whether this counter should start off enabled.
When this is set, the counter will immediately start being recorded as soon as it is created.
By default, this is false.
Sourcepub fn inherit(&mut self, inherit: bool) -> &mut Self
pub fn inherit(&mut self, inherit: bool) -> &mut Self
Set whether this counter is inherited by new threads.
When this flag is set, this counter observes activity in new threads created by any thread already being observed.
By default, the flag is unset: counters are not inherited, and observe only the threads specified when they are created.
This flag cannot be set if the counter belongs to a Group
. Doing so
will result in an error when the counter is built. This is a kernel
limitation.
Sourcepub fn pinned(&mut self, pinned: bool) -> &mut Self
pub fn pinned(&mut self, pinned: bool) -> &mut Self
Set whether the counter is pinned to the PMU.
If this flag is set, the kernel will attempt to keep the counter on
always on the CPU if at all possible. If it fails to do so, the counter
will enter an error state where reading it will always return EOF. For
this crate, that would result in Counter::read
returning an error
with kind ErrorKind::UnexpectedEof
.
This option only applies to hardware counters and group leaders. At this time this crate provides no way to configure group leaders so this option will only work when the resulting counter is not in a group.
This is false by default.
Sourcepub fn exclusive(&mut self, exclusive: bool) -> &mut Self
pub fn exclusive(&mut self, exclusive: bool) -> &mut Self
Controls whether the counter or group can be scheduled onto a CPU alongside other counters or groups.
This is false by default.
Sourcepub fn exclude_user(&mut self, exclude_user: bool) -> &mut Self
pub fn exclude_user(&mut self, exclude_user: bool) -> &mut Self
Whether we should exclude events that occur in user space.
This is false by default.
Sourcepub fn exclude_kernel(&mut self, exclude_kernel: bool) -> &mut Self
pub fn exclude_kernel(&mut self, exclude_kernel: bool) -> &mut Self
Whether we should exclude events that occur in kernel space.
Note that setting this to false may result in permission errors if
the current perf_event_paranoid
value is greater than 1.
This is true by default.
Sourcepub fn include_kernel(&mut self) -> &mut Self
pub fn include_kernel(&mut self) -> &mut Self
Include kernel code.
See exclude_kernel
.
Sourcepub fn exclude_hv(&mut self, exclude_hv: bool) -> &mut Self
pub fn exclude_hv(&mut self, exclude_hv: bool) -> &mut Self
Whether we should exclude events that happen in the hypervisor.
This is not supported on all architectures as it required built-in support within the CPU itself.
Note that setting this to false may result in permission errors if
the current perf_event_paranoid
value is greater than 1.
This is true by default
Sourcepub fn include_hv(&mut self) -> &mut Self
pub fn include_hv(&mut self) -> &mut Self
Include hypervisor code.
See exclude_hv
.
Sourcepub fn exclude_idle(&mut self, exclude_idle: bool) -> &mut Self
pub fn exclude_idle(&mut self, exclude_idle: bool) -> &mut Self
Whether to exclude events that occur when running the idle task.
Note that this only has an effect for software events.
Sourcepub fn mmap(&mut self, mmap: bool) -> &mut Self
pub fn mmap(&mut self, mmap: bool) -> &mut Self
Enable the generation of MMAP records for executable memory maps.
MMAP records are emitted when the process/thread that is being observed creates a new executable memory mapping.
Sourcepub fn comm(&mut self, comm: bool) -> &mut Self
pub fn comm(&mut self, comm: bool) -> &mut Self
Enable the tracking of process command name changes.
This can happen when a process calls execve(2)
, prctl(PR_SET_NAME)
,
or writes to /proc/self/comm
.
If you also set the comm_exec
flag, then the
kernel will indicate which of these process name changes were due to
calls to execve(2)
.
Sourcepub fn sample_period(&mut self, period: u64) -> &mut Self
pub fn sample_period(&mut self, period: u64) -> &mut Self
Set the period at which the kernel will generate sample events.
As an example, if the event is Hardware::INSTRUCTIONS
and period
is 100_000 then every 100_000 instructions the kernel will generate an
event.
Note that the actual precision at which the sample corresponds to the
instant and location at which Nth event occurred is controlled by the
precise_ip
option.
This setting is mutually exclusive with sample_frequency
.
Sourcepub fn sample_frequency(&mut self, frequency: u64) -> &mut Self
pub fn sample_frequency(&mut self, frequency: u64) -> &mut Self
Set the frequency at which the kernel will generate sample events (in Hz).
Note that this is not guaranteed to be exact. The kernel will adjust the period to attempt to keep the desired frequency but the rate at which events occur varies drastically then samples may not occur at the specified frequency.
The amount to which samples correspond to the instant and location at
which an event occurred is controlled by the precise_ip
option.
This setting is mutually exclusive with sample_period
.
Sourcepub fn inherit_stat(&mut self, inherit_stat: bool) -> &mut Self
pub fn inherit_stat(&mut self, inherit_stat: bool) -> &mut Self
Save event counts on context switch for inherited tasks.
This option is only meaningful if inherit
is also enabled.
Sourcepub fn enable_on_exec(&mut self, enable_on_exec: bool) -> &mut Self
pub fn enable_on_exec(&mut self, enable_on_exec: bool) -> &mut Self
Enable the counter automatically after a call to execve(2)
.
Sourcepub fn task(&mut self, task: bool) -> &mut Self
pub fn task(&mut self, task: bool) -> &mut Self
If set, then the kernel will generate fork and exit records.
Sourcepub fn wakeup_watermark(&mut self, watermark: usize) -> &mut Self
pub fn wakeup_watermark(&mut self, watermark: usize) -> &mut Self
Set how many bytes will be written before the kernel sends an overflow notification.
This controls how much data will be emitted before
Sampler::next_blocking
will wake up once blocked.
This setting is mutually exclusive with wakeup_events
.
Sourcepub fn wakeup_events(&mut self, events: usize) -> &mut Self
pub fn wakeup_events(&mut self, events: usize) -> &mut Self
Set how many samples will be written before the kernel sends an overflow notification.
This controls how much data will be emitted before
Sampler::next_blocking
will wake up once blocked. Note that only
sample records (PERF_RECORD_SAMPLE
) count towards the event count.
Some caveats apply, see the manpage for the full documentation.
This method is mutually exclusive with wakeup_watermark
.
Sourcepub fn precise_ip(&mut self, skid: SampleSkid) -> &mut Self
pub fn precise_ip(&mut self, skid: SampleSkid) -> &mut Self
Control how much skid is permitted when recording events.
Skid is the number of instructions that occur between an event occuring and a sample being gathered by the kernel. Less skid is better but there are hardware limitations around how small the skid can be.
Also see SampleSkid
.
Sourcepub fn mmap_data(&mut self, mmap_data: bool) -> &mut Self
pub fn mmap_data(&mut self, mmap_data: bool) -> &mut Self
Enable the generation of MMAP records for non-executable memory maps.
This is the data counterpart of mmap
.
Sourcepub fn sample_id_all(&mut self, sample_id_all: bool) -> &mut Self
pub fn sample_id_all(&mut self, sample_id_all: bool) -> &mut Self
If enabled, then a subset of the sample fields will additionally be
included in most non-PERF_RECORD_SAMPLE
samples.
See the manpage for the exact fields that are included and which records include the trailer.
Sourcepub fn exclude_host(&mut self, exclude_host: bool) -> &mut Self
pub fn exclude_host(&mut self, exclude_host: bool) -> &mut Self
Only collect measurements for events occurring inside a VM instance.
This is only meaningful when profiling from outside the VM instance.
See the manpage for more documentation.
Sourcepub fn exclude_guest(&mut self, exclude_guest: bool) -> &mut Self
pub fn exclude_guest(&mut self, exclude_guest: bool) -> &mut Self
Don’t collect measurements for events occurring inside a VM instance.
This is only meaningful when profiling from outside the VM instance.
See the manpage for more documentation.
Sourcepub fn exclude_callchain_kernel(&mut self, exclude_kernel: bool) -> &mut Self
pub fn exclude_callchain_kernel(&mut self, exclude_kernel: bool) -> &mut Self
Do not include stack frames in the kernel when gathering callchains as a part of recording a sample.
Sourcepub fn exclude_callchain_user(&mut self, exclude_user: bool) -> &mut Self
pub fn exclude_callchain_user(&mut self, exclude_user: bool) -> &mut Self
Do not include stack frames from userspace when gathering a callchain as a part of recording a sample.
Sourcepub fn mmap2(&mut self, mmap2: bool) -> &mut Self
pub fn mmap2(&mut self, mmap2: bool) -> &mut Self
Generate an extended executable mmap record.
This record has enough info to uniquely identify which instance of a
shared map it corresponds to. Note that you also need to set the mmap
option for this to work.
Sourcepub fn comm_exec(&mut self, comm_exec: bool) -> &mut Self
pub fn comm_exec(&mut self, comm_exec: bool) -> &mut Self
Check whether the kernel will annotate COMM records with the COMM_EXEC
bit when they occur due to an execve(2)
call.
This option doesn’t actually change the behaviour of the kernel. Instead, it is useful for feature detection.
Sourcepub fn clockid(&mut self, clockid: impl Into<Option<Clock>>) -> &mut Self
pub fn clockid(&mut self, clockid: impl Into<Option<Clock>>) -> &mut Self
Select which linux clock to use for timestamps.
If clockid
is None
then the kernel will use an internal timer. This
timer may not be any of the options for clockid.
See Clock
and the clock_getttime(2)
manpage for
documentation on what the different clock values mean.
Sourcepub fn context_switch(&mut self, context_switch: bool) -> &mut Self
pub fn context_switch(&mut self, context_switch: bool) -> &mut Self
Generate SWITCH
records when a context switch occurs.
Also enables the generation of SWITCH_CPU_WIDE
records if profiling
in cpu-wide mode.
Sourcepub fn namespaces(&mut self, namespaces: bool) -> &mut Self
pub fn namespaces(&mut self, namespaces: bool) -> &mut Self
Generate NAMESPACES
records when a task enters a new namespace.
Sourcepub fn ksymbol(&mut self, ksymbol: bool) -> &mut Self
pub fn ksymbol(&mut self, ksymbol: bool) -> &mut Self
Generate KSYMBOL
records when kernel symbols are registered or
unregistered.
Sourcepub fn bpf_event(&mut self, bpf_event: bool) -> &mut Self
pub fn bpf_event(&mut self, bpf_event: bool) -> &mut Self
Generate BPF_EVENT
records when eBPF programs are loaded or unloaded.
Sourcepub fn aux_output(&mut self, aux_output: bool) -> &mut Self
pub fn aux_output(&mut self, aux_output: bool) -> &mut Self
Output data for non-aux events to the aux buffer, if supported by the hardware.
Sourcepub fn cgroup(&mut self, cgroup: bool) -> &mut Self
pub fn cgroup(&mut self, cgroup: bool) -> &mut Self
Generate CGROUP
records when a new cgroup is created.
Sourcepub fn text_poke(&mut self, text_poke: bool) -> &mut Self
pub fn text_poke(&mut self, text_poke: bool) -> &mut Self
Generate TEXT_POKE
records when the kernel text (i.e. code) is
modified.
Sourcepub fn build_id(&mut self, build_id: bool) -> &mut Self
pub fn build_id(&mut self, build_id: bool) -> &mut Self
Whether to include the build id in MMAP2
events.
Sourcepub fn inherit_thread(&mut self, inherit_thread: bool) -> &mut Self
pub fn inherit_thread(&mut self, inherit_thread: bool) -> &mut Self
Only inherit the counter to new threads in the same process, not to other processes.
Sourcepub fn remove_on_exec(&mut self, remove_on_exec: bool) -> &mut Self
pub fn remove_on_exec(&mut self, remove_on_exec: bool) -> &mut Self
Disable this counter when it successfully calls execve(2)
.
Sourcepub fn sigtrap(&mut self, sigtrap: bool) -> &mut Self
pub fn sigtrap(&mut self, sigtrap: bool) -> &mut Self
Synchronously send SIGTRAP
to the process that created the counter
when the sampled events overflow.
Sourcepub fn sig_data(&mut self, sig_data: u64) -> &mut Self
pub fn sig_data(&mut self, sig_data: u64) -> &mut Self
Copy data to the user’s signal handler (via si_perf
in siginfo_t
).
This can be used to figure out which event caused the signal to be sent.
It does nothing unless sigtrap
is also set to true
.
Sourcepub fn branch_sample_type(&mut self, flags: SampleBranchFlag) -> &mut Self
pub fn branch_sample_type(&mut self, flags: SampleBranchFlag) -> &mut Self
Specify which branches to include in the branch record.
This does nothing unless SampleFlag::BRANCH_STACK
is specified in
the sample flags.
Sourcepub fn sample_regs_user(&mut self, regs: u64) -> &mut Self
pub fn sample_regs_user(&mut self, regs: u64) -> &mut Self
Specify which CPU registers to dump in a sample.
This does nothing unless SampleFlag::REGS_USER
is part of the
specified sample
flags.
The actual layout of the register mask is architecture specific.
You will generally want the PERF_REG_<arch>
constants in
perf_event_open_sys
. (e.g. PERF_REG_X86_SP
).
Sourcepub fn sample_regs_intr(&mut self, regs: u64) -> &mut Self
pub fn sample_regs_intr(&mut self, regs: u64) -> &mut Self
Specify which CPU registers to dump in a sample.
This does nothing unless SampleFlag::REGS_INTR
is part of the
specified sample
flags.
The actual layout of the register mask is architecture specific.
You will generally want the PERF_REG_<arch>
constants in
perf_event_open_sys
. (e.g. PERF_REG_X86_SP
).
Sourcepub fn sample_stack_user(&mut self, stack: u32) -> &mut Self
pub fn sample_stack_user(&mut self, stack: u32) -> &mut Self
Specify the maximum size of the user stack to dump.
This option does nothing unless SampleFlag::STACK_USER
is set in the
sample flags.
Note that the size of the array allocated within the sample record will
always be exactly this size, even if the actual collected stack data is
much smaller. The allocated sample buffer (when constructing a
Sampler
) will need to be large enough to accommodate the chosen
stack size or else samples will be lost.
Sourcepub fn sample_max_stack(&mut self, max_stack: u16) -> &mut Self
pub fn sample_max_stack(&mut self, max_stack: u16) -> &mut Self
Specify the maximum number of stack frames to include when unwinding the user stack.
This does nothing unless SampleFlag::CALLCHAIN
is set in the sample
flags.
Note that the kernel has a user configurable limit specified at
/proc/sys/kernel/perf_event_max_stack
. Setting sample_max_stack
to
larger than that limit will result in an EOVERFLOW
error when building
the counter.
Sourcepub fn aux_watermark(&mut self, watermark: u32) -> &mut Self
pub fn aux_watermark(&mut self, watermark: u32) -> &mut Self
Specify how much data is required before the kernel emits an AUX record.
Sourcepub fn aux_sample_size(&mut self, sample_size: u32) -> &mut Self
pub fn aux_sample_size(&mut self, sample_size: u32) -> &mut Self
Specify the desired size of AUX data.
This does nothing unless SampleFlag::AUX
is set in the sample flags.
Note that the emitted aux data can be smaller than the requested size.