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
printa
formatting 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
printf
format conversions. The Cprintf
routine requires that you indicate the size of arguments by adding prefixes such as%ld
forlong
, or%lld
forlong long
. The D compiler is aware of the size and type of your arguments, so these prefixes are not required in your Dprintf
statements. -
DTrace provides additional format characters that are useful for debugging and observability. For example, the
%a
format 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
, andX
conversions— the field is padded with leading zeroes—the number of digits to appear after the radix character for thee
,E
, andf
conversions. -
The maximum number of significant digits for the
g
andG
conversions. -
Or the maximum number of bytes to be printed from a string by the
s
conversion.
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
h
specifies that a followingd
,i
,o
,u
,x
, orX
conversion applies to ashort
or unsignedshort
. -
An optional
l
specifies that a followingd
,i
,o
,u
,x
, orX
conversion applies to along
or unsignedlong
. -
An optional
ll
specifies that a followingd
,i
,o
,u
,x
, orX
conversion applies to along long
or unsignedlong long
. -
An optional
L
specifies that a followinge
,E
,f
,g
, orG
conversion applies to along
double. -
An optional
l
specifies that a followingc
conversion applies to awint_t
argument, and that a followings
conversion character applies to a pointer to awchar_t
argument.
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 forprinta
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 yourprinta
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 theprinta
format 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+0x6
trace 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.