Home / Alt manpages / perf-script-perl(1)

  • perf-script-perl(1)
  • User command
  • linux

Build a Perl Event Handler for perf Trace Data

Turning a raw perf trace into a useful count means writing a Perl handler, and perf script -g perl generates the boilerplate for you. This walkthrough records scheduler wake-up events, generates a Perl starter from the trace, and turns it into a handler that counts wake-ups by process. Allow about twenty minutes if perf and its kernel tools are already installed.

Examples use the installed Linux tools common package, version 6.8.0-142.142, and the perf-script-perl(1) manual dated 1 September 2026. The matching kernel-specific perf binary is not available on this machine, so the command output below is the expected shape from the documented interface, not a claim that the full recording workflow ran here.

This workflow reads a trace and writes a script in the current directory. Recording with -a observes the whole system and may expose process names and timing data, so use it only on a machine where that collection is acceptable. Nothing here changes a service or kernel setting, and normal use does not need root.

1. Check the local tools

Confirm the package and the command lookup first. These are read-only checks:

$ dpkg-query -W -f='${Package} ${Version}\n' linux-tools-common
linux-tools-common 6.8.0-142.142
$ command -v perf
/usr/bin/perf
$ perf --version
WARNING: perf not found for kernel 6.8.0-139

That last line is a packaging trap: the wrapper exists, but this running kernel needs a matching kernel-specific tools package. Install that through your normal package-management process before continuing, using the package name your own warning prints (it is kernel-specific, so do not copy one from elsewhere). Do not treat the presence of /usr/bin/perf as proof that recording works.

Checkpoint

Continue only when perf --version reports a usable perf build without the missing-tools warning.

2. Record one scheduler event type

Change to a disposable working directory, then record scheduler wake-ups for a short interval:

$ mkdir -p "$HOME/perf-perl-example"
$ cd "$HOME/perf-perl-example"
$ perf record -a -e sched:sched_wakeup -- sleep 5
[ perf record output varies by perf version ]

The manual uses perf record -a -e sched:sched_wakeup as its example. Here -a enables system-wide collection, -e selects the event, and sleep 5 supplies the workload and duration. This normally creates perf.data in the current directory.

Recording is not destructive, but the trace can be large and may hold sensitive workload metadata. Remove it once you no longer need it.

Warning

If recording fails with a permissions or event-availability error, stop and inspect the error rather than reaching for sudo automatically. Elevated access may be required by the host's perf policy, but granting it changes who can collect system-wide trace data.

3. Generate the Perl starter

With perf.data in the same directory, ask perf to generate a Perl script:

$ perf script -g perl
generated Perl script: perf-script.pl
$ test -s perf-script.pl && echo 'starter created'
starter created

The manual says this starter has a handler for each event type present in the trace and prints every available field. The exact filename message can vary, so verify the file itself rather than trusting the printed name:

$ sed -n '1,100p' perf-script.pl
$ rg -n 'sched::sched_wakeup|Perf::Trace|trace_begin|trace_end' perf-script.pl

Keep the generated file as a reference. It shows the handler signature for the trace you actually recorded, which is safer than guessing argument positions from a different event.

4. Replace the handler with a useful count

Edit a copy so the original starter stays around for comparison:

$ cp --preserve=all perf-script.pl wakeup-count.pl
$ editor wakeup-count.pl

Keep the module setup perf generated. In the sched::sched_wakeup handler, the documented argument order is the common event values followed by $comm, $pid, $prio, $success and $target_cpu. Add a counter and a report at the end of processing:

my %wakeups;

sub sched::sched_wakeup
{
    my ($event_name, $context, $common_cpu, $common_secs,
        $common_nsecs, $common_pid, $common_comm,
        $comm, $pid, $prio, $success, $target_cpu) = @_;
    $wakeups{$comm}++;
}

sub trace_end
{
    for my $comm (sort keys %wakeups) {
        print "$comm $wakeups{$comm}\n";
    }
}

If your trace contains a different event, use the generated handler's own spelling and signature instead of this one. Unhandled event types are ignored unless the script defines trace_unhandled, which is useful when you deliberately record more event types than the report needs.

5. Run and verify the report

Process the recorded data with the script:

$ perf script -s perl:wakeup-count.pl
systemd 42
worker 17
$ test "${PIPESTATUS[0]}" -eq 0 && echo 'trace processed'
trace processed

The names and counts are host-specific, so do not expect to match them. What matters is that the command exits successfully and the output contains the process names you saw in the trace. Run perf script without -s if you need to inspect raw decoded events before debugging the Perl logic.

Tip

For a compact timing calculation, the manual's Perf::Trace::Util module provides nsecs, nsecs_str and avg. The event handler receives seconds and nanoseconds separately, so use those utility functions rather than assuming the timestamp is a single floating-point value.

6. Keep, share or remove the trace safely

The script is plain text and can be reviewed or versioned freely. The trace is different: it may reveal process names and system activity. Inspect either file and apply your normal data-handling rules before copying it off the host.

When finished, remove only this example directory after checking that no result is still needed:

$ ls -l "$HOME/perf-perl-example"
$ rm -r "$HOME/perf-perl-example"

Warning

That final command is irreversible for the files in that directory. If you need recovery, stop before running it and copy the directory to approved storage instead. The recording and script never alter the system, so there is no service rollback step to worry about.

Done means

  • A kernel-matched perf build passes the local availability check.
  • perf record created a trace containing the event your handler names.
  • perf script -g perl produced a starter based on that trace.
  • The handler uses the generated event signature and reports a checked result.
  • Trace data is retained only as long as its sensitivity and usefulness justify it.