]> Sergey Matveev's repositories - dmon.git/commitdiff
More optimizations and improvements
authorSergey Matveev <stargrave@stargrave.org>
Wed, 7 Sep 2022 19:57:32 +0000 (22:57 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Wed, 7 Sep 2022 19:57:32 +0000 (22:57 +0300)
dmon.pl

diff --git a/dmon.pl b/dmon.pl
index 161622894982b2709caeb6ca178a6b6b81f52933..5ef1845d1f33c410aa6c9ea7eddb49b4c6ebedde 100755 (executable)
--- 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;
+}