6 Output Formatting
WARNING:
Oracle Linux 7 is now in Extended Support. See Oracle Linux Extended Support and Oracle Open Source Support Policies for more information.
Migrate applications and data to Oracle Linux 8 or Oracle Linux 9 as soon as possible.
For more information about DTrace, see Oracle Linux: DTrace Release Notes and Oracle Linux: Using DTrace for System Tracing.
DTrace provides the built-in printf and
printaformatting functions, which you can use
from your D programs to format output. The D compiler provides
features that are not found in the C library's
printf() routine, so be sure to read this
chapter even if you are already familiar with
printf.
This chapter also discusses the formatting behavior of the
trace function and the default output format
that is used by the dtrace command to display
aggregations.
printf Action
The printf action combines the ability to trace
data, as if by the trace function, but with the
ability to output the data and other text in a specific format
that you describe. The printf function directs
DTrace to trace the data associated with each argument after the
first argument and then format the results using the rules
described by the first printf argument, known
as a format string. The format string is a
regular string that contains any number of format conversions,
each beginning with a % character, that
describe how to format the corresponding argument. The first
conversion in the format string corresponds to the second
printf argument, the second conversion to the
third argument, and so on. All of the text between conversions is
printed verbatim. The character following the %
conversion character describes the format to use for the
corresponding argument.
Unlike the C library's printf() function,
DTrace's printf function is a built-in function
that is recognized by the D compiler. The D compiler provides
several useful services for the DTrace printf
function that are not found in printf(),
including the following:
-
The D compiler compares the arguments to the conversions in the format string. If an argument's type is incompatible with the format conversion, the D compiler provides an error message explaining the problem.
-
The D compiler does not require the use of size prefixes with
printfformat conversions. The Cprintfroutine requires that you indicate the size of arguments by adding prefixes such as%ldforlong, or%lldforlong long. The D compiler is aware of the size and type of your arguments, so these prefixes are not required in your Dprintfstatements. -
DTrace provides additional format characters that are useful for debugging and observability. For example, the
%aformat conversion can be used to print a pointer as a symbol name and offset.
To implement these features, you must specify the format string in
the DTrace printf function as a string constant
in your D program. Format strings cannot be dynamic variables of
type string.
Conversion Specifications
Each conversion specification in the format string is introduced
by the % character, after which the following
information appears in sequence:
-
Zero or more flags (in any order), that modify the meaning of the conversion specification, as described in Flag Specifiers.
-
An optional minimum field width. If the converted value has fewer bytes than the field width, the value is padded with spaces on the left, by default, or on the right, if the left-adjustment flag (
-) is specified. The field width can also be specified as an asterisk (*), in which case the field width is set dynamically, based on the value of an additional argument of typeint. -
An optional precision specifier that indicates the following:
-
The minimum number of digits to appear for the
d,i,o,u,x, andXconversions— the field is padded with leading zeroes—the number of digits to appear after the radix character for thee,E, andfconversions. -
The maximum number of significant digits for the
gandGconversions. -
Or the maximum number of bytes to be printed from a string by the
sconversion.
The precision specifier takes the form of a period (
.), followed by either an asterisk (*), as described in Width and Precision Specifiers, or a decimal digit string. -
-
An optional sequence of size prefixes that indicate the size of the corresponding argument. Size prefixes are not required in D, but are provided for compatibility with the C
printf()function. -
A conversion specifier that indicates the type of conversion to be applied to the argument.
The C printf() function also supports
conversion specifications of the form
%n$, where
n is a decimal integer. Note that the
DTrace printf function does not support this
type of conversion specification.
Flag Specifiers
printf conversion flags are enabled by
specifying one or more of the following characters, which can
appear in any order, as described in the following table.
| Flag Specifier | Description |
|---|---|
|
|
The integer portion of the result of a decimal
conversion ( |
|
|
The result of the conversion is left-justified within the field. The conversion is right-justified if this flag is not specified. |
|
|
The result of signed conversion always begins with a
sign ( |
|
|
If the first character of a signed conversion is not
a sign or if a signed conversion results in no
characters, a space is placed before the result. If
the |
|
|
The value is converted to an alternate form if an alternate form is defined for the selected conversion. The alternate formats for conversions are described along with the corresponding conversion. |
|
|
For |
Width and Precision Specifiers
The minimum field width can be specified as a decimal-digit
string following any flag specifier, in which case the field
width is set to the specified number of columns. The field width
can also be specified as asterisk (*) in
which case an additional argument of type int
is accessed to determine the field width.
For example, to print an integer x in a field
width determined by the value of the int
variable w, you would write the following D
statement:
printf("%*d", w, x);
The field width can also be specified with a
? character to indicate that the field width
should be set based on the number of characters required to
format an address (in hexadecimal) in the data model of the
operating system kernel. The width is set to
8, if the kernel is using the 32-bit data
model, or to 16, if the kernel is using the
64-bit data model. The precision for the conversion can be
specified as a decimal digit string following a period
(.), or by an asterisk (*)
following a period. If an asterisk is used to specify the
precision, an additional argument of type int
before the conversion argument provides the precision. If both
width and precision are specified as asterisks, the order of
arguments to printf for the conversion should
appear in the following order: width, precision, value.
Size Prefixes
Size prefixes are required in ANSI C programs that use
printf() to indicate the size and type of the
conversion argument. The D compiler performs this processing for
your printf calls automatically, so size
prefixes are not required. Although size prefixes are provided
for C compatibility, their use is explicitly discouraged in D
programs because they bind your code to a particular data model
when using derived types.
For example, if a typedef is redefined to
different integer base types depending on the data model, it is
not possible to use a single C conversion that works in both
data models without explicitly knowing the two underlying types
and including a cast expression or defining multiple format
strings. The D compiler solves this problem automatically by
enabling you to omit size prefixes and automatically determining
the argument size.
Size prefixes can be placed just prior to the format conversion name and after any flags, widths, and precision specifiers and are as follows:
-
An optional
hspecifies that a followingd,i,o,u,x, orXconversion applies to ashortor unsignedshort. -
An optional
lspecifies that a followingd,i,o,u,x, orXconversion applies to alongor unsignedlong. -
An optional
llspecifies that a followingd,i,o,u,x, orXconversion applies to along longor unsignedlong long. -
An optional
Lspecifies that a followinge,E,f,g, orGconversion applies to alongdouble. -
An optional
lspecifies that a followingcconversion applies to awint_targument, and that a followingsconversion character applies to a pointer to awchar_targument.
Conversion Formats
| Conversion Characters | Description |
|---|---|
|
|
The pointer or |
|
|
Identical to |
|
|
The |
|
|
The |
|
|
The |
|
|
The |
|
|
The |
|
|
The |
|
|
The |
|
|
The |
|
|
The |
|
|
The pointer or |
|
|
The argument must be an array of
|
|
|
The argument must be an array of
|
|
|
The |
|
|
The |
|
|
The argument must be an array of
|
|
|
The |
|
|
The |
|
|
Print a literal |
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 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 forprintadoes 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 yourprintaoutput 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 theprintaformat string. -
The aggregation result is included in the output by using the additional
@format flag character, which is only valid when used withprinta. 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 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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+0x6trace Default Format
If you use trace rather than
printf to capture data, the
dtrace command formats the results by using a
default output format. If the data is 1, 2, 4, or 8 bytes in size,
the result is formatted as a decimal integer value. If the data is
any other size, and is a sequence of printable characters if
interpreted as a sequence of bytes, it is printed as an ASCII
string. If the data is any other size, and is not a sequence of
printable characters, it is printed as a series of byte values
that is formatted as hexadecimal integers.