Ao agregar dados durante algum período de tempo, talvez você queira normalizar os dados em relação a algum fator de constante. Essa técnica permite que você compare dados separados com mais facilidade. Por exemplo, ao agregar chamadas do sistema, talvez você queira resultados de chamadas do sistema como uma taxa por segundo em vez de um valor absoluto durante o curso da execução. A ação normalize() do DTrace permite que você normalize os dados dessa forma. Os parâmetros de normalize() são uma agregação e um fator de normalização. O resultado da agregação mostra cada valor dividido pelo fator de normalização.
O exemplo a seguir mostra como agregar dados por chamada do sistema:
#pragma D option quiet BEGIN { /* * Get the start time, in nanoseconds. */ start = timestamp; } syscall:::entry { @func[execname] = count(); } END { /* * Normalize the aggregation based on the number of seconds we have * been running. (There are 1,000,000,000 nanoseconds in one second.) */ normalize(@func, (timestamp - start) / 1000000000); }
A execução do script acima por um breve período de tempo gera o seguinte resultado em um computador desktop:
# dtrace -s ./normalize.d ^C syslogd 0 rpc.rusersd 0 utmpd 0 xbiff 0 in.routed 1 sendmail 2 echo 2 FvwmAuto 2 stty 2 cut 2 init 2 pt_chmod 3 picld 3 utmp_update 3 httpd 4 xclock 5 basename 6 tput 6 sh 7 tr 7 arch 9 expr 10 uname 11 mibiisa 15 dirname 18 dtrace 40 ksh 48 java 58 xterm 100 nscd 120 fvwm2 154 prstat 180 perfbar 188 Xsun 1309 .netscape.bin 3005 |
normalize() define o fator de normalização da agregação especificada, mas essa ação não modifica os dados subjacentes. A função denormalize() possui somente uma agregação. Ao adicionar a ação denormalize ao exemplo anterior, são retornadas contagens de chamada do sistema sem processamento e taxas por segundo:
#pragma D option quiet BEGIN { start = timestamp; } syscall:::entry { @func[execname] = count(); } END { this->seconds = (timestamp - start) / 1000000000; printf("Ran for %d seconds.\n", this->seconds); printf("Per-second rate:\n"); normalize(@func, this->seconds); printa(@func); printf("\nRaw counts:\n"); denormalize(@func); printa(@func); }
A execução do script acima por um breve período de tempo produz um resultado similar ao seguinte exemplo:
# dtrace -s ./denorm.d ^C Ran for 14 seconds. Per-second rate: syslogd 0 in.routed 0 xbiff 1 sendmail 2 elm 2 picld 3 httpd 4 xclock 6 FvwmAuto 7 mibiisa 22 dtrace 42 java 55 xterm 75 adeptedit 118 nscd 127 prstat 179 perfbar 184 fvwm2 296 Xsun 829 Raw counts: syslogd 1 in.routed 4 xbiff 21 sendmail 30 elm 36 picld 43 httpd 56 xclock 91 FvwmAuto 104 mibiisa 314 dtrace 592 java 774 xterm 1062 adeptedit 1665 nscd 1781 prstat 2506 perfbar 2581 fvwm2 4156 Xsun 11616 |
As agregações também podem ser renormalizadas. Se normalize() for chamada mais de uma vez para a mesma agregação, o fator de normalização será o fator especificado na chamada mais recente. O exemplo a seguir imprime taxas por segundo ao longo do tempo:
#pragma D option quiet BEGIN { start = timestamp; } syscall:::entry { @func[execname] = count(); } tick-10sec { normalize(@func, (timestamp - start) / 1000000000); printa(@func); }