Die Funktion printa() dient zum Formatieren der Ergebnisse von Aggregaten in D-Programmen. Die Funktion wird in einer von zwei Formen aufgerufen:
printa(@Aggregationsname); printa(Formatzeichenkette, @Aggregationsname);
Bei Verwendung der ersten Form erstellt der Befehl dtrace(1M) eine vollständige Momentaufnahme der Aggregatdaten und wendet auf die Ausgabe das entsprechende Standardausgabeformat für Aggregate (siehe Beschreibung in Kapitel 9Aggregate) an.
Bei Verwendung der zweiten Form erstellt der Befehl dtrace(1M) ebenfalls eine vollständige Momentaufnahme der Aggregatdaten und generiert eine Ausgabe gemäß den in der Format-Zeichenkette angegebenen Umwandlungen. Dabei gelten die folgenden Regeln:
Die Formatumwandlungen müssen mit der Tupelsignatur übereinstimmen, die zur Aggregaterzeugung verwendet wurde. Jedes Tupelelement darf nur einmal auftreten. Wenn wir beispielsweise eine Zählung mit den folgenden D-Anweisungen aggregieren:
@a["hello", 123] = count(); @a["goodbye", 456] = count();
und dann einer Prüfpunktklausel die D-Anweisung printa(Format-Zeichenkette, @a) hinzufügen, erstellt dtrace eine Momentaufnahme der Aggregatdaten und erzeugt die Ausgabe so, als hätten wir die folgenden Anweisungen eingegeben:
printf(Format-Zeichenkette, "hello", 123); printf(Format-Zeichenkette, "goodbye", 456);
und so fort mit jedem im Aggregat definierten Tupel.
Im Gegensatz zu printf() muss die Format-Zeichenkette für printa() nicht alle Tupelelemente enthalten. Das heißt, es ist durchaus möglich, bei einem Tupel mit drei Elementen nur eine Formatumwandlung zu verwenden. Sie können deshalb beliebige Tupelschlüssel aus der printa()-Ausgabe ausschließen, indem Sie diese in der Aggregatdeklaration an das Ende des Tupels verschieben und in der printa()-Format-Zeichenkette keine Umwandlungskennungen für sie angeben.
Das Aggregatergebnis kann durch das zusätzliche Format-Flag @ in die Ausgabe aufgenommen werden. Dieses ist nur im Zusammenhang mit printa() gültig. Das Flag @ kann mit jeder geeigneten Formatumwandlungskennung kombiniert werden und darf in einer Format-Zeichenkette mehrmals auftreten. Das bedeutet, dass das Tupelergebnis an jeder Stelle und mehrmals in der Ausgabe auftreten kann. Welche Umwandlungskennungen für die einzelnen Aggregatfunktionen zulässig sind, ist durch den Ergebnistyp der jeweiligen Aggregatfunktion bedingt. Diese lauten:
avg() |
uint64_t |
count() |
uint64_t |
lquantize() |
int64_t |
max() |
uint64_t |
min() |
uint64_t |
quantize() |
int64_t |
sum() |
uint64_t |
Um beispielsweise das Ergebnis von avg() zu formatieren, können wir die Formatumwandlungen %d, %i, %o, %u oder %x anwenden. Die Funktionen quantize() und lquantize() formatieren ihre Ergebnisse nicht als Einzelwerte, sondern als ASCII-Tabellen.
Das folgende D-Programm stellt ein vollständiges Beispiel für printa() dar. Darin wird der Wert von caller mit dem Provider profile geprüft und die Ergebnisse werden anschließend in Form einer einfachen Tabelle ausgegeben:
profile:::profile-997 { @a[caller] = count(); } END { printa("%@8u %a\n", @a); }
Wenn Sie dieses Programm mit dtrace ausführen, warten Sie einige Sekunden lang und drücken Sie dann Strg-C. Sie erhalten eine Ausgabe der Art:
# dtrace -s printa.d ^C CPU ID FUNCTION:NAME 1 2 :END 1 0x1 1 ohci`ohci_handle_root_hub_status_change+0x148 1 specfs`spec_write+0xe0 1 0xff14f950 1 genunix`cyclic_softint+0x588 1 0xfef2280c 1 genunix`getf+0xdc 1 ufs`ufs_icheck+0x50 1 genunix`infpollinfo+0x80 1 genunix`kmem_log_enter+0x1e8 ... |