if ($#ARGV < 0) {
die "Usage: $0 [tcp|ifname0 ifname1 ...]\n";
-};
+}
use File::Temp qw/tempfile/;
my ($dfh, $dfn) = tempfile();
-END { unlink $dfn };
+END { unlink $dfn if defined $dfn }
print $dfh "
#pragma D option quiet
#pragma D option switchrate=10Hz
-
-profile:::tick-1sec
-{
- printf(\"T\\n\");
-}\n";
+";
if ($ARGV[0] eq "tcp") {
sub tcpprobe {
my ($probe, $dir) = @_;
args[4]->tcp_sport,
args[2]->ip_daddr,
args[4]->tcp_dport] = sum(args[2]->ip_plength);
- " . $dir . "pkts++;
+ @" . $dir . "pkts = count();
+ @" . $dir . "bytes = sum(args[2]->ip_plength);
}\n";
- };
+ }
tcpprobe "tcp:::send", "tx";
tcpprobe "tcp:::receive", "rx";
print $dfh '
profile:::tick-1sec
{
printa("< [%s]:%d [%s]:%d %@d\n", @rx);
- clear(@rx);
+ trunc(@rx);
printa("> [%s]:%d [%s]:%d %@d\n", @tx);
- clear(@tx);
- printf("I %d\n", rxpkts);
- printf("O %d\n", txpkts);
- rxpkts = 0;
- txpkts = 0;
- printf("T\n");
+ trunc(@tx);
+ printa("T %@d %@d %@d %@d\n", @rxpkts, @txpkts, @rxbytes, @txbytes);
+ clear(@rxpkts);
+ clear(@txpkts);
+ clear(@rxbytes);
+ clear(@txbytes);
}';
} else {
sub ipprobe {
{
@" . $dir . "[args[2]->ip_saddr,
args[2]->ip_daddr] = sum(args[2]->ip_plength);
- " . $dir . "pkts++;
+ @" . $dir . "pkts = count();
+ @" . $dir . "bytes = sum(args[2]->ip_plength);
}\n";
- };
+ }
ipprobe "ip:::send", "tx";
ipprobe "ip:::receive", "rx";
print $dfh '
profile:::tick-1sec
{
printa("< %s %s %@d\n", @rx);
- clear(@rx);
+ trunc(@rx);
printa("> %s %s %@d\n", @tx);
- clear(@tx);
- printf("I %d\n", rxpkts);
- printf("O %d\n", txpkts);
- rxpkts = 0;
- txpkts = 0;
- printf("T\n");
+ trunc(@tx);
+ printa("T %@d %@d %@d %@d\n", @rxpkts, @txpkts, @rxbytes, @txbytes);
+ clear(@rxpkts);
+ clear(@txpkts);
+ clear(@rxbytes);
+ clear(@txbytes);
}';
-};
+}
-my $height = (defined $ENV{DMON_HEIGHT}) ? $ENV{DMON_HEIGHT} : 40;
+my $height = (exists $ENV{DMON_HEIGHT}) ? $ENV{DMON_HEIGHT} : 40;
$height--;
########################################################################
my ($s, $suffix, $bounds) = @_;
foreach my $i (0 .. $#{$bounds}) {
next if $s < @{$bounds}[$i];
- return sprintf "%.2f %s%s", $s / @{$bounds}[$i], $sizePrefix[$i], $suffix;
- };
- return "$s $suffix";
+ return sprintf "%.2f%s%s", $s / @{$bounds}[$i], $sizePrefix[$i], $suffix;
+ }
+ return "$s$suffix";
}
sub humanCount { return human shift, "", \@countBound }
-sub humanSize { return human shift, "iB", \@sizeBound }
-#
+sub humanSize { return human shift, "B", \@sizeBound }
+
########################################################################
-my (%tx, %rx);
-my ($pktsRx, $pktsTx, $bytesRx, $bytesTx) = (0, 0, 0, 0);
+my $allRxPkts1;
+my $allRxPkts5;
+my $allRxPkts10;
+my $allTxPkts1;
+my $allTxPkts5;
+my $allTxPkts10;
+my $allRxBytes1;
+my $allRxBytes5;
+my $allRxBytes10;
+my $allTxBytes1;
+my $allTxBytes5;
+my $allTxBytes10;
+my $allRxBytesPeak;
+my $allTxBytesPeak;
+my $totalBytes1;
+my $totalBytes5;
+my $totalBytes10;
+my $totalBytesPeak;
format STDOUT_TOP =
-@>>>>>>>>>> / @<<<<<<<<<< @>>>>>>>>>>>> / @<<<<<<<<<<<<
-humanCount($pktsRx), humanCount($pktsTx), humanSize($bytesRx), humanSize($bytesTx)
-------------------------------------------------------------------------
+Rx: @|||||| @|||||| @|||||| @|||||| @|||||| @|||||| peak: @||||||
+humanCount($allRxPkts1), humanCount($allRxPkts5), humanCount($allRxPkts10), humanSize($allRxBytes1), humanSize($allRxBytes5), humanSize($allRxBytes10), humanSize($allRxBytesPeak)
+Tx: @|||||| @|||||| @|||||| @|||||| @|||||| @|||||| peak: @||||||
+humanCount($allTxPkts1), humanCount($allTxPkts5), humanCount($allTxPkts10), humanSize($allTxBytes1), humanSize($allTxBytes5), humanSize($allTxBytes10), humanSize($allTxBytesPeak)
+Total: @|||||| @|||||| @|||||| peak: @||||||
+humanSize($totalBytes1), humanSize($totalBytes5), humanSize($totalBytes10), humanSize($totalBytesPeak)
+----------------------------------------------------------------------------------------------------
.
-my ($left, $dir, $right, $size);
+my $left;
+my $dir;
+my $right;
+my $bytes1;
+my $bytes5;
+my $bytes10;
format STDOUT =
-@<<<<<<<<<<<<<<<<<<<<<<<<<< @| @>>>>>>>>>>>>>>>>>>>>>>>>>> @>>>>>>>>>>>>
-$left, $dir, $right, humanSize($size)
+@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @|| @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @|||||| @|||||| @||||||
+$left, $dir, $right, humanSize($bytes1), humanSize($bytes5), humanSize($bytes10)
.
########################################################################
+close $dfh;
my $dexec;
-open $dexec, "-|", "dtrace -s $dfn" or die "$!";
-sleep 1;
+if (exists $ENV{DMON_ONLY_SCRIPT}) {
+ open $dexec, "<", "$dfn" or die "$!";
+ while (<$dexec>) { print }
+ exit;
+}
+if (exists $ENV{DMON_ONLY_PARSE}) {
+ $dexec = \*STDIN;
+} else {
+ open $dexec, "-|", "dtrace -s $dfn" or die "$!";
+ sleep 1;
+}
unlink $dfn;
-my $xx;
+my %bytes = ("<" => {}, ">" => {});
+my %seen = ("<" => {}, ">" => {});
+my @allRxPkts = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+my @allTxPkts = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+my @allRxBytes = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+my @allTxBytes = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+my @totalBytes = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
while (<$dexec>) {
- next unless /^[<>TIO]/;
+ next unless /^[<>T]/;
my @cols = split;
if ($cols[0] eq "T") {
+ unshift @allRxPkts, $cols[1]; pop @allRxPkts;
+ unshift @allTxPkts, $cols[2]; pop @allTxPkts;
+ unshift @allRxBytes, $cols[3]; pop @allRxBytes;
+ unshift @allTxBytes, $cols[4]; pop @allTxBytes;
+ unshift @totalBytes, $cols[3] + $cols[4]; pop @totalBytes;
+ if ($cols[3] > $allRxBytesPeak) { $allRxBytesPeak = $cols[3] }
+ if ($cols[4] > $allTxBytesPeak) { $allTxBytesPeak = $cols[4] }
+ if (($cols[3] + $cols[4]) > $totalBytesPeak) {
+ $totalBytesPeak = $cols[3] + $cols[4];
+ }
+
+ my $sum = $allRxPkts[0];
+ $allRxPkts1 = $sum;
+ foreach (@allRxPkts[1 .. 4]) { $sum += $_ }
+ $allRxPkts5 = $sum / 5;
+ foreach (@allRxPkts[5 .. 9]) { $sum += $_ }
+ $allRxPkts10 = $sum / 10;
+
+ $sum = $allTxPkts[0];
+ $allTxPkts1 = $sum;
+ foreach (@allTxPkts[1 .. 4]) { $sum += $_ }
+ $allTxPkts5 = $sum / 5;
+ foreach (@allTxPkts[5 .. 9]) { $sum += $_ }
+ $allTxPkts10 = $sum / 10;
+
+ $allRxBytes1 = $sum;
+ foreach (@allRxBytes[1 .. 4]) { $sum += $_ }
+ $allRxBytes5 = $sum / 5;
+ foreach (@allRxBytes[5 .. 9]) { $sum += $_ }
+ $allRxBytes10 = $sum / 10;
+
+ $sum = $allTxBytes[0];
+ $allTxBytes1 = $sum;
+ foreach (@allTxBytes[1 .. 4]) { $sum += $_ }
+ $allTxBytes5 = $sum / 5;
+ foreach (@allTxBytes[5 .. 9]) { $sum += $_ }
+ $allTxBytes10 = $sum / 10;
+
+ $sum = $totalBytes[0];
+ $totalBytes1 = $sum;
+ foreach (@totalBytes[1 .. 4]) { $sum += $_ }
+ $totalBytes5 = $sum / 5;
+ foreach (@totalBytes[5 .. 9]) { $sum += $_ }
+ $totalBytes10 = $sum / 10;
+
my @res;
- foreach my $src (keys %rx) {
- foreach my $dst (keys %{$rx{$src}}) {
- push @res, [$dst, "<", $src, $rx{$src}{$dst}];
- };
- };
- foreach my $src (keys %tx) {
- foreach my $dst (keys %{$tx{$src}}) {
- push @res, [$src, ">", $dst, $tx{$src}{$dst}];
- };
- };
+ foreach my $dir (keys %bytes) {
+ foreach my $src (keys %{$bytes{$dir}}) {
+ foreach my $dst (keys %{$bytes{$dir}{$src}}) {
+ my $vals = $bytes{$dir}{$src}{$dst};
+ if ((not exists $seen{$dir}{$src}) or
+ (not exists $seen{$dir}{$src}{$dst})) {
+ unshift @{$vals}, 0;
+ }
+ if ($#{$vals} >= 10) {
+ $bytes{$dir}{$src}{$dst} = [@{$vals}[0 .. 9]];
+ }
+ my @r = ($dir eq "<") ? ($dst, "<=", $src) : ($src, "=>", $dst);
+ $sum = $vals->[0];
+ push @r, $sum;
+ foreach (@{$vals}[1 .. 4]) { $sum += $_ }
+ push @r, $sum;
+ foreach (@{$vals}[5 .. 9]) { $sum += $_ }
+ if ($sum == 0) {
+ delete $bytes{$dir}{$src}{$dst};
+ next;
+ }
+ push @r, $sum;
+ push @res, \@r;
+ }
+ }
+ }
@res = sort { @{$b}[-1] <=> @{$a}[-1] } @res;
printf "\033[H\033[J";
$- = 0;
- foreach (@res[0..$height]) {
+ foreach (@res[0 .. $height]) {
last unless defined;
- ($left, $dir, $right, $size) = @{$_};
+ ($left, $dir, $right, $bytes1, $bytes5, $bytes10) = @{$_};
+ $bytes5 /= 5;
+ $bytes10 /= 10;
write STDOUT;
- };
- (%rx, %tx) = (), ();
- ($pktsRx, $pktsTx, $bytesRx, $bytesTx) = (0, 0, 0, 0);
- next;
- };
- if ($cols[0] eq "I") {
- $pktsRx += $cols[1];
- next;
- };
- if ($cols[0] eq "O") {
- $pktsTx += $cols[1];
+ }
+
+ %seen = ("<" => {}, ">" => {});
next;
- };
- if ($cols[0] eq "<") {
- $xx = \%rx;
- $pktsRx++;
- $bytesRx += $cols[3];
- } else {
- $xx = \%tx;
- $pktsTx++;
- $bytesTx += $cols[3];
- };
- if (defined ${$xx}{$cols[1]}) {
- ${$xx}{$cols[1]}{$cols[2]} += $cols[3];
- } else {
- ${$xx}{$cols[1]} = {$cols[2] => $cols[3]};
- };
-};
+ }
+ if (not exists $bytes{$cols[0]}{$cols[1]}) {
+ %{$bytes{$cols[0]}{$cols[1]}} = ();
+ }
+ if (not exists $bytes{$cols[0]}{$cols[1]}{$cols[2]}) {
+ @{$bytes{$cols[0]}{$cols[1]}{$cols[2]}} = (0, 0, 0, 0, 0, 0, 0, 0, 0);
+ }
+ unshift @{$bytes{$cols[0]}{$cols[1]}{$cols[2]}}, $cols[3];
+ if (not exists $seen{$cols[0]}{$cols[1]}) {
+ %{$seen{$cols[0]}{$cols[1]}} = ();
+ }
+ $seen{$cols[0]}{$cols[1]}{$cols[2]} = 1;
+}