6.2 printa Action

The printa action enables you to format the results of aggregations in a D program. The function is invoked by using one of following two forms:

printa(@aggregation-name); 
printa(format-string, @aggregation-name);

If the first form of the function is used, the dtrace command takes a consistent snapshot of the aggregation data and produces output that is equivalent to the default output format used for aggregations. See Chapter 3, Aggregations. If the second form of the function is used, the dtrace command takes a consistent snapshot of the aggregation data and produces output according to the conversions that are specified in the format string, according to the following rules:

  • The format conversions must match the tuple signature that is used to create the aggregation. Each tuple element can only appear once. For example, if you aggregate a count by using the following D statements:

    @a["hello", 123] = count(); 
    @a["goodbye", 456] = count();

    Then, you add the D statement printa(format-string, @a) to a probe clause, dtrace takes a snapshot of the aggregation data and produces output as though you entered these statements:

    printf(format-string, "hello", 123); 
    printf(format-string, "goodbye", 456);

    Then, continue similarly on for each tuple defined in the aggregation.

  • Unlike printf, the format string that you use for printa does not need to include all elements of the tuple: you can have a tuple of length 3 and only one format conversion. Therefore, you can omit any tuple keys from your printa output by changing your aggregation declaration to move the keys you want to omit to the end of the tuple and then omit any corresponding conversion specifiers for them in the printa format string.

  • The aggregation result is included in the output by using the additional @ format flag character, which is only valid when used with printa. The @ flag can be combined with any appropriate format conversion specifier. Also, the flag can appear more than once in a format string so that your tuple result can appear anywhere in the output, as well as appear more than once. The set of conversion specifiers that can be used with each aggregating function are implied by the aggregating function's result type. The aggregation result types are listed in the following table.

Aggregation

Result Type

avg

uint64_t

count

uint64_t

llquantize

int64_t

lquantize

int64_t

max

uint64_t

min

uint64_t

quantize

int64_t

sum

uint64_t

For example, to format the results of avg, you can apply the %d, %i, %o, %u, or %x format conversions. The quantize, lquantize, and llquantize functions format their results as an ASCII table rather than as a single value.

The following D program shows an example of printa using the profile provider to sample the value of caller, then formatting the results as a simple table. Type the following source code and save it in a file named printa.d:

profile:::tick-1000
{
  @myagg[caller] = count();
}

END
{
  printa("%@8u %a\n", @myagg);
}

If you use the dtrace command to execute this program, wait a few seconds, then press Ctrl-C. You should see output similar to the following:

# dtrace -qs printa.d 
^C
       1 vmlinux`do_syscall_64+0x2f
       1 vmlinux`___bpf_prog_run+0x528
       1 vmlinux`page_frag_free+0x3e
       1 vmlinux`__legitimize_mnt
       1 vmlinux`seq_printf+0x1b
       1 vmlinux`selinux_sb_show_options+0x39
       1 vmlinux`strchr+0x1f
       1 ip6_tables`ip6t_do_table+0xbb
       2 vmlinux`__raw_callee_save___pv_queued_spin_unlock+0x10
      14 libata`__dta_ata_sff_pio_task_1036+0x9e
   12975 vmlinux`native_safe_halt+0x6