web-dev-qa-db-fra.com

Comment obtenir des statistiques de réseau en temps réel sous Linux au format Ko / Mo / Bytes et pour un ID de processus de port ou d'application spécifique?

J'ai utilisé IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Aucun d'entre eux ne m'aide à trouver les paquets en temps réel qui sont envoyés/reçus de mon application au format KB ou MB. La raison en est que je suis en train d’écrire une application, où je dois être très sûr que ma compression est correcte, mais je ne peux pas tester pour avancer.

Que puis-je utiliser pour suivre des statistiques de réseau en temps réel très spécifiques et précises?

enter image description here

21
YumYumYum

Votre application envoie probablement des paquets à un numéro de port UDP ou TCP spécifique ou à une adresse IP spécifique.

Vous pouvez donc utiliser quelque chose comme TCPdump pour capturer ce trafic.

TCPdump ne vous donne pas les statistiques en temps réel que vous désirez, mais vous pouvez alimenter sa sortie avec quelque chose qui le fait (j'essaierai de mettre à jour cette réponse avec une réponse plus tard).


Mettre à jour:

$ 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

Je l'ai interrompu après une minute en appuyant sur Ctrl + C.

Vous devez ajouter une expression de filtre appropriée à la fin de la commande tcpdump pour n'inclure que le trafic généré par votre application (par exemple, port 123).

Le programme netbps est ceci:

#!/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;
    }
  }
}

Ce n'est qu'un exemple, ajustez-vous au goût.

25
RedGrittyBrick

Utilisation comme ci-dessous du même dossier:

Pour vérifier le packer par interface: ./netpps.sh eth0

Pour vérifier la vitesse par interface: ./netspeed.sh eth0

Mesurer les paquets par seconde sur une interface netpps.sh en tant que nom de fichier

#!/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

Mesurer la bande passante réseau sur une interface netspeed.sh en tant que nom de fichier

#!/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

Veuillez vous référer à ce site pour plus d’informations http://xmodulo.com/measure-packets-per-second-throughput-high-speed-network-interface.html

13

Plus facile à utiliser et plus facile à contrôler la sortie et à rediriger vers le fichier pour la journalisation continue:

ifstat

Vient probablement avec la plupart des distributions Linux, et peut être installé avec Brew sur Mac

4
samthebest

Je pense que vous pouvez utiliser l'interface proc pour obtenir les informations dont vous avez besoin. J'ai créé ce petit script Shell appelé rt_traf.sh:

#!/bin/bash

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

Ceci imprimera les octets d'entrée et de sortie séparés par un onglet. Les octets multipliés par 8 vous donneront des bits/seconde et ensuite divisés par 10 ^ 6 vous donneront des mégabits/seconde. Bien sûr, vous pouvez ajouter ceci au script Shell pour formater la sortie comme vous le souhaitez. Vous pouvez appeler ceci avec le PID de votre application comme so ./rt_traf.sh <PID> qui vous donnera une lecture instantanée de votre application depuis le démarrage. Pour voir les statistiques en temps réel par seconde, vous pouvez envelopper le script Shell dans la commande watch:

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

Le paramètre -n peut être ajusté au minimum en dixièmes de seconde. Pour faire un calcul au fil du temps, je ferais quelque chose comme ceci:

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"

Encore une fois, le calcul peut être ajusté pour la taille/le temps dont vous avez besoin. Ce n’est pas la solution la plus élégante ni celle qui est emballée dans un film rétractable, mais elle devrait fonctionner à la rigueur.

3
d34dh0r53

J'avais juste besoin de mesurer le trafic mysql entrant et sortant sur un ancien système où Perl ne fonctionnait pas correctement. Je ne pouvais donc pas m'empêcher d'écrire quelques lignes d'awk servant le même objectif de mesure du trafic total vu par tcpdump:

# 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

Et si vous préférez les one-liners, en voici un pour vous:

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;}'
2

Chaque application peut être réalisée avec une règle de pare-feu utilisant xtables et une modification de celle-ci.

Cela ne répond pas à la question "par application" mais juste à "par interface".

Vous trouverez ci-dessous un script qui fonctionne sur la plupart des routeurs Linux intégrés, tels que ceux compatibles avec Ubiquiti et OpenWRT, et extrait ses détails de/proc/net/dev.

(Et facile à changer pour les paquets, etc.)

#!/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;

Copiez ce qui précède dans votre presse-papiers, puis dans une session de terminal sur votre routeur:

$ cat > /tmp/n.sh

puis: Ctrl + V (ou clic droit/coller)

puis: Ctrl + D

$ chmod +x /tmp/n.sh

$ /tmp/n.sh eth0

Vous pouvez également le coller dans un bloc-notes, puis répétez ce qui précède si vous devez le modifier - tous les routeurs intégrés ne disposent pas d'un éditeur! Assurez-vous de tout copier du # en haut au fini. au fond.

L'exemple de netpps ci-dessus est génial BTW - mais tous les périphériques n'ont pas de système de fichiers monté/sys. Vous devrez peut-être également changer/bin/bash en/bin/sh ou vice versa.

Source: https://Gist.github.com/dagelf/ab2bad26ce96fa8d79b0834cd8cab549

0
Dagelf