Wie erhalte ich Echtzeit-Netzwerkstatistiken in Linux im KB / MB / Bytes-Format und für bestimmte Port- oder Anwendungsprozess-IDs?

22

Früher habe ich IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Keiner von ihnen hilft mir dabei, Echtzeitpakete zu finden, die von meiner Anwendung im KB- oder MB-Format gesendet / empfangen werden. Der Grund dafür ist, dass ich eine Anwendung schreibe, bei der ich sehr sicher sein muss, dass meine Komprimierung korrekt ist, aber ich kann nicht testen, um vorwärts zu kommen.

Was kann ich verwenden, um sehr spezifische und genaue Echtzeit-Netzwerkstatistiken zu verfolgen?

Bildbeschreibung hier eingeben

Yum Yum yum
quelle

Antworten:

27

Ihre Anwendung sendet wahrscheinlich Pakete an eine bestimmte UDP- oder TCP-Portnummer oder an eine bestimmte IP-Adresse.

Sie können daher so etwas wie TCPdump verwenden, um diesen Datenverkehr zu erfassen.

TCPdump gibt Ihnen nicht die Echtzeit-Statistiken, die Sie wünschen, aber Sie können die Ausgabe an eine Funktion weiterleiten, die dies tut (ich werde versuchen, diese Antwort später mit einer Antwort zu aktualisieren).


Aktualisieren:

$ sudo tcpdump -i eth1 -l -e -n | ./netbps
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
11:36:53    2143.33 Bps
11:37:03    1995.99 Bps
11:37:13    2008.35 Bps
11:37:23    1999.97 Bps
11:37:33    2083.32 Bps
131 packets captured
131 packets received by filter
0 packets dropped by kernel

Ich unterbrach das nach einer Minute durch Drücken von Strg + C.

Sie müssen am Ende des tcpdumpBefehls einen geeigneten Filterausdruck hinzufügen, um nur den von Ihrer App generierten Datenverkehr zu berücksichtigen (z. B. port 123).

Das Programm netbpssieht so aus:

#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes;

my $reporting_interval = 10.0; # seconds
my $bytes_this_interval = 0;
my $start_time = [Time::HiRes::gettimeofday()];

STDOUT->autoflush(1);

while (<>) {
  if (/ length (\d+):/) {
    $bytes_this_interval += $1;
    my $elapsed_seconds = Time::HiRes::tv_interval($start_time);
    if ($elapsed_seconds > $reporting_interval) {
       my $bps = $bytes_this_interval / $elapsed_seconds;
       printf "%02d:%02d:%02d %10.2f Bps\n", (localtime())[2,1,0],$bps;
       $start_time = [Time::HiRes::gettimeofday()];
       $bytes_this_interval = 0;
    }
  }
}

Es ist nur ein Beispiel, passen Sie sich dem Geschmack an.

RedGrittyBrick
quelle
Vielen Dank, ich werde auf Ihr Arbeitsbeispiel warten. Mein Ziel war, wie ich es mit $ bwm-ng -o plain -N -d getan habe, das die Ausgabe als Bit von Interfaces anzeigt, aber das schlägt fehl, wenn das Interface mit Ausnahme von lo verwendet wird. Andererseits zeigt der IPtraf hervorragende Bytes in Echtzeit. Aber es gibt keine Werkzeuge , die mir wie Bits und Bytes in Echtzeit in RX / TX für bestimmte Schnittstelle oder jede Schnittstelle als Gesamt sagen kann , etc. Ich bin es fehlt :-(
YumYumYum
@ YumYum: Antwort aktualisiert.
RedGrittyBrick
1
@RedGrittyBrick Du absolute Legende! Tolles Drehbuch! Vielen Dank für das Teilen. Das beantwortet meine Frage an superuser.com/questions/395226/...
Eamorr
Dieser sollte in busybox bash auf eingebetteten Routern funktionieren
Dagelf
Dies wird auch mitvnstat -tr
St0rM
14

Verwendung wie unten aus demselben Ordner:

So überprüfen Sie den Packer pro Schnittstelle: ./netpps.sh eth0

So überprüfen Sie die Geschwindigkeit pro Schnittstelle: ./netspeed.sh eth0

Messen Sie Pakete pro Sekunde auf einem Interface netpps.sh als Dateinamen

#!/bin/bash

INTERVAL="1"  # update interval in seconds

if [ -z "$1" ]; then
        echo
        echo usage: $0 [network-interface]
        echo
        echo e.g. $0 eth0
        echo
        echo shows packets-per-second
        exit
fi

IF=$1

while true
do
        R1=`cat /sys/class/net/$1/statistics/rx_packets`
        T1=`cat /sys/class/net/$1/statistics/tx_packets`
        sleep $INTERVAL
        R2=`cat /sys/class/net/$1/statistics/rx_packets`
        T2=`cat /sys/class/net/$1/statistics/tx_packets`
        TXPPS=`expr $T2 - $T1`
        RXPPS=`expr $R2 - $R1`
        echo "TX $1: $TXPPS pkts/s RX $1: $RXPPS pkts/s"
done

Messen Sie die Netzwerkbandbreite auf einer Schnittstelle netspeed.sh als Dateinamen

#!/bin/bash

INTERVAL="1"  # update interval in seconds

if [ -z "$1" ]; then
        echo
        echo usage: $0 [network-interface]
        echo
        echo e.g. $0 eth0
        echo
        exit
fi

IF=$1

while true
do
        R1=`cat /sys/class/net/$1/statistics/rx_bytes`
        T1=`cat /sys/class/net/$1/statistics/tx_bytes`
        sleep $INTERVAL
        R2=`cat /sys/class/net/$1/statistics/rx_bytes`
        T2=`cat /sys/class/net/$1/statistics/tx_bytes`
        TBPS=`expr $T2 - $T1`
        RBPS=`expr $R2 - $R1`
        TKBPS=`expr $TBPS / 1024`
        RKBPS=`expr $RBPS / 1024`
        echo "TX $1: $TKBPS kB/s RX $1: $RKBPS kB/s"
done

Weitere Informationen finden Sie auf dieser Website unter http://xmodulo.com/measure-packets-per-second-throughput-high-speed-network-interface.html

Muthukumar Anbalagan
quelle
Dies ist keine praktikable Lösung für "bestimmte Port- oder Anwendungsprozess-ID", da nur die Rate pro Schnittstelle angegeben wird.
Mene
6

Am einfachsten zu verwenden und am einfachsten zu steuern, um die Ausgabe zu steuern und zur fortlaufenden Protokollierung in eine Datei umzuleiten:

ifstat

Kommt wahrscheinlich mit den meisten Linux-Distributionen und kann mit Brew auf dem Mac installiert werden

samthebest
quelle
Dank dafür. Wie vertragen sich die anderen mit dem Mac? Ich werde versuchen, ifstat zu installieren und zu sehen, wie es geht. Weitere Informationen wären auf jeden Fall hilfreich gewesen.
Nyxee
3

Ich denke, Sie können die Proc-Schnittstelle verwenden, um die Informationen zu erhalten, die Sie benötigen. Ich habe dieses kleine Shell-Skript namens rt_traf.sh erstellt:

#!/bin/bash

cat /proc/$1/net/netstat | grep 'IpExt: ' | tail -n 1 | awk '{ print $8 "\t" $9 }'

Dadurch werden die durch einen Tabulator getrennten In- und Out-Oktetts gedruckt. Oktette multipliziert mit 8 ergeben Bits / Sekunde und dividiert durch 10 ^ 6 ergeben Megabits / Sekunde. Natürlich können Sie dies dem Shell-Skript hinzufügen, um die Ausgabe nach Ihren Wünschen zu formatieren. Sie können dies mit der PID Ihrer Anwendung wie ./rt_traf.sh <PID>folgt aufrufen, um eine sofortige Anzeige Ihrer Anwendung seit dem Start zu erhalten. Um Echtzeit-Statistiken pro Sekunde zu sehen, können Sie das Shell-Skript in den Befehl watch einbinden:

watch -n 1 ./rt_traf.sh <PID>

Der -nParameter kann auf Zehntelsekunden genau eingestellt werden. Um eine Berechnung über einen längeren Zeitraum durchzuführen, würde ich Folgendes tun:

PID=<PID>; START=`./rt_traf.sh $PID`;IN_START=`echo $START | awk '{ print $1 }'`; OUT_START=`echo $START | awk '{ print $2 }'`; sleep 10; END=`./rt_traf.sh $PID`; IN_END=`echo $END | awk '{ print $1 }'`; OUT_END=`echo $END | awk '{ print $2 }'`; IN_BPS=`echo "scale=2; (($IN_START-$IN_END)/10)/8" | bc`; OUT_BPS=`echo "scale=2; (($OUT_START-$OUT_END)/10)/8" | bc`; echo "In: " $IN_BPS "Bits/second"; echo "Out: " $OUT_BPS "Bits/second"

Wieder kann die Mathematik für die Größe / Zeiten angepasst werden, die Sie benötigen. Nicht die eleganteste oder in Schrumpffolie verpackte Lösung, sollte aber im Notfall funktionieren.

d34dh0r53
quelle
3
Das ist falsch. / proc / <PID> / net / netstat enthält keine Prozessdaten.
nab
So erweitern Sie den Kommentar von nab: /proc/<pid>/net/netstatGibt dieselben Daten zurück wie z proc/net/netstat. Sie erhalten für alle Prozesse die gleichen Daten.
EML
2

Ich musste nur messen, wie viel MySQL-Datenverkehr auf einem alten System ein- und ausgeht, auf dem Perl nicht ordnungsgemäß funktioniert hat. Daher konnte ich nicht widerstehen, einige Zeilen awk zu schreiben, die dem gleichen Ziel dienen, den Gesamtdatenverkehr von tcpdump zu messen:

# tcpdump -l -e -n port 3306 | \
  awk '{
  t=substr($1, 0, 8);
  n=substr($9, 0, length($9)-1);
  if(t != pt){
    print t, sum;
    sum = 0;
  } else {
    sum += n
  }
  pt=t;
}'

tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
14:41:54 
14:41:55 466905
14:41:56 765220
14:41:57 741511
14:41:58 688219
14:41:59 492322
14:42:00 800087
14:42:01 1248608
14:42:02 1276476
14:42:03 755586
14:42:04 1029453
14:42:05 818298
^C32515 packets captured
32633 packets received by filter
107 packets dropped by kernel

Und wenn Sie Einzeiler besser mögen, ist hier einer für Sie:

tcpdump -l -e -n port 3306 | awk '{t=substr($1,0,8);n=substr($9,0,length($9)-1);if(t!=pt){print t,sum;sum=0;}else{sum+=n}pt=t;}'
Aurimas Mikalauskas
quelle
Die elseAnweisung sollte entfernt werden, da sonst Zeilen übersprungen werden und sumnicht korrekt sind. tcpdump -l -e -n port 3306 | awk '{t=substr($1,0,8);n=substr($9,0,length($9)-1);if(t!=pt){print t,sum;sum=0;};sum+=n;pt=t;}
David
0

Pro Anwendung kann mit einer Firewall-Regel unter Verwendung von xtables und einer Modifikation der folgenden Regeln gearbeitet werden.

Dies beantwortet nicht die Frage "pro Anwendung", sondern nur die Frage "pro Schnittstelle".

Unten finden Sie ein Skript, das auf den meisten eingebetteten Linux-Routern wie Ubiquiti und OpenWRT funktioniert und dessen Details aus / proc / net / dev abgerufen werden.

(Und leicht zu Paketen usw. zu ändern)

#!/bin/sh

SLP=1 # output / sleep interval
DEVICE=$1
IS_GOOD=0
for GOOD_DEVICE in `grep \: /proc/net/dev | awk -F: '{print $1}'`; do
    if [ "$DEVICE" = $GOOD_DEVICE ]; then
        IS_GOOD=1
        break
    fi
done

if [ $IS_GOOD -eq 0 ]; then
    echo "Device not found. Should be one of these:"
        grep ":" /proc/net/dev | awk -F: '{print $1}' | sed s@\ @@g 
    exit 1
fi

while true; do

LINE=`grep $1 /proc/net/dev | sed s/.*://`;
RECEIVED1=`echo $LINE | awk '{print $1}'`
TRANSMITTED1=`echo $LINE | awk '{print $9}'`
TOTAL=$(($RECEIVED1+$TRANSMITTED1))

sleep $SLP

LINE=`grep $1 /proc/net/dev | sed s/.*://`;
RECEIVED2=`echo $LINE | awk '{print $1}'`
TRANSMITTED2=`echo $LINE | awk '{print $9}'`
SPEED=$((($RECEIVED2+$TRANSMITTED2-$TOTAL)/$SLP))
INSPEED=$((($RECEIVED2-$RECEIVED1)/$SLP))
OUTSPEED=$((($TRANSMITTED2-$TRANSMITTED1)/$SLP))

printf "In: %12i KB/s | Out: %12i KB/s | Total: %12i KB/s\n" $(($INSPEED/1024)) $(($OUTSPEED/1024)) $((($INSPEED+$OUTSPEED)/1024)) ;

done;

Kopieren Sie das Obige in Ihre Zwischenablage und dann in einer Terminalsitzung auf Ihrem Router:

$ cat > /tmp/n.sh

dann: Strg + V (oder Rechtsklick / Einfügen)

dann: Strg + D

$ chmod +x /tmp/n.sh

$ /tmp/n.sh eth0

Sie können es auch in einen Notizblock einfügen und dann den obigen Vorgang wiederholen, wenn Sie es bearbeiten müssen - nicht alle eingebetteten Router verfügen über einen Editor! Stellen Sie sicher, dass Sie alles von der # oben auf die fertig kopieren; unten.

Das obige netpps-Beispiel ist übrigens großartig - aber nicht alle Geräte haben ein eingehängtes / sys-Dateisystem. Möglicherweise müssen Sie auch / bin / bash in / bin / sh ändern oder umgekehrt.

Quelle: https://gist.github.com/dagelf/ab2bad26ce96fa8d79b0834cd8cab549

Dagelf
quelle
Bitte posten Sie nicht die gleiche Antwort auf mehrere Fragen. Wenn dieselben Informationen tatsächlich beide Fragen beantworten, sollte eine Frage (normalerweise die neuere) als Duplikat der anderen geschlossen werden. Sie können dies anzeigen, indem Sie abstimmen, um es als Duplikat zu schließen, oder, wenn Sie nicht genug Reputation dafür haben , ein Flag setzen, um anzuzeigen, dass es sich um ein Duplikat handelt. Passen Sie andernfalls Ihre Antwort auf diese Frage an und fügen Sie dieselbe Antwort nicht an mehreren Stellen ein.
DavidPostill
Sie haben genau den gleichen Kommentar in meinem anderen Beitrag gepostet ... der übrigens angepasst wurde ... Diese Art von Antwort lässt mich nur fragen, warum ich mir die Zeit genommen habe, hier einen Beitrag zu leisten.
Dagelf
Wenn es angepasst wurde, geschah dies, nachdem die Posts vom System automatisch markiert wurden. Ich habe nicht die Zeit, jedes Wort zu lesen, um zu sehen, ob es angepasst ist oder nicht.
DavidPostill
1
Die einzige Anpassung, die Sie vorgenommen haben, war das Hinzufügen von zwei Sätzen zu Beginn Ihres Ansers. Der Rest scheint identisch zu sein. Und diese beiden Sätze waren in der ursprünglichen Antwort nicht als veröffentlicht enthalten - weshalb sie automatisch als doppelte Antwort gekennzeichnet wurde.
DavidPostill