A função printa() é usada para formatar os resultados de agregações em um programa em D. A função é chamada de uma de duas formas:
printa(@aggregation-name); printa(format-string, @aggregation-name);
Se o primeiro formato da função for usado, o comando dtrace(1M) tirará um instantâneo consistente dos dados da agregação e produzirá uma saída equivalente ao formato de saída padrão usado para agregações, descrito no Capítulo 9Agregações.
Se o segundo formato da função for usado, o comando dtrace(1M) tirará um instantâneo consistente dos dados da agregação e produzirá uma saída de acordo com as conversões especificadas na seqüência de formato, de acordo com as seguintes regras.
As conversões de formato devem corresponder à assinatura de tupla usada para criar a agregação. Cada elemento de tupla só pode aparecer uma vez. Por exemplo, se você agregar uma contagem usando as declarações de D seguintes:
@a["hello", 123] = count(); @a["goodbye", 456] = count();
e, em seguida, adicionar a declaração de D printa(seqüência de formato, @a) a uma cláusula de teste, dtrace tirará um instantâneo dos dados da agregação e produzirá uma saída, se você tiver inserido as declarações:
printf(format-string, "hello", 123); printf(format-string, "goodbye", 456);
e assim por diante para cada tupla definida na agregação.
Ao contrário de printf(), a seqüência de formato usada para printa() não precisa incluir todos os elementos da tupla. Ou seja, você pode ter uma tupla de tamanho 3 e apenas uma conversão de formato. Portanto, você pode omitir quaisquer chaves de tupla da saída de printa(), alterando a declaração de agregação para mover as chaves que você deseja omitir para o fim da tupla e, em seguida, omitir os especificadores de conversão correspondentes delas na seqüência de formato printa() .
O resultado da agregação pode ser incluído na saída, usando o caractere de sinalizador de formato adicional @, que só é válido quando usado com printa(). O sinalizador @ pode ser combinado com qualquer especificador de conversão de formato apropriado, e pode aparecer mais de uma vez em uma seqüência de formato, para que o resultado da tupla possa aparecer em qualquer local na saída e possa aparecer mais de uma vez. O conjunto de especificadores de conversão que podem ser usados com cada função de agregação são deduzidos pelo tipo de resultado da função de agregação. Os tipos de resultado de agregação são:
avg() |
uint64_t |
count() |
uint64_t |
lquantize() |
int64_t |
max() |
uint64_t |
min() |
uint64_t |
quantize() |
int64_t |
sum() |
uint64_t |
Por exemplo, para formatar os resultados de avg(), você pode aplicar as conversões de formato %d, %i, %o, %u ou %x. As funções quantize() e lquantize() formatam seus resultados como uma tabela ASCII em vez de um único valor.
O programa em D seguinte mostra um exemplo completo de printa (), usando o provedor de perfil profile para fazer uma amostra do valor de caller e, em seguida, formatando os resultados como uma tabela simples:
profile:::profile-997 { @a[caller] = count(); } END { printa("%@8u %a\n", @a); }
Se você usar o dtrace para executar este programa, espere alguns segundos, e pressione Control-C, para ver uma saída semelhante ao exemplo seguinte:
# 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 ... |