From: Sergey Matveev Date: Wed, 7 Sep 2022 19:57:32 +0000 (+0300) Subject: More optimizations and improvements X-Git-Url: http://www.git.stargrave.org/?p=dmon.git;a=commitdiff_plain;h=c4f14778299c61600cc32ce3122c0adfd5eb9d30 More optimizations and improvements --- diff --git a/dmon.pl b/dmon.pl index 1616228..5ef1845 100755 --- a/dmon.pl +++ b/dmon.pl @@ -21,18 +21,14 @@ use warnings; 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) = @_; @@ -43,23 +39,24 @@ $probe 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 { @@ -71,27 +68,28 @@ $probe { @" . $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--; ######################################################################## @@ -104,86 +102,179 @@ sub human { 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; +}