Comment obtenir des statistiques réseau en temps réel sous Linux au format KB / MB / Bytes et pour un port ou une application processID spécifique?


22

Je IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Aucun d'eux ne m'aide à trouver des paquets en temps réel qui sont envoyés / reçus à partir de mon application au format KB ou MB. La raison en est que j'écris 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?

entrez la description de l'image ici

Réponses:


27

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 à quelque chose qui fait (j'essaierai de mettre à jour cette réponse avec une réponse plus tard).


Mise à 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

J'ai interrompu cela après une minute en appuyant sur Ctrl + C.

Vous devez ajouter une expression de filtre appropriée à la fin de la tcpdumpcommande pour inclure uniquement le trafic généré par votre application (par exemple port 123)

Le programme netbpsest le suivant:

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

C'est juste un exemple, ajustez au goût.


Merci beaucoup, j'attendrai votre exemple de travail. Mon objectif était comme je l'ai fait avec $ bwm-ng -o plain -N -d qui affiche la sortie sous forme de bits par les interfaces mais qui échoue si l'interface est utilisée sauf lo. En revanche, l'IPtraf affiche d'excellents octets en temps réel. Mais il n'y a aucun outil qui puisse me dire comme des bits et des octets en temps réel dans RX / TX pour une interface spécifique ou une interface au total, etc. Je le manque :-(
YumYumYum

@YumYum: réponse mise à jour.
RedGrittyBrick

1
@RedGrittyBrick Vous légende absolue! Grand script! Merci beaucoup d'avoir partagé. Cela répond à ma question sur superuser.com/questions/395226/…
Eamorr

Celui-ci devrait fonctionner dans busybox bash sur des routeurs intégrés: gist.github.com/dagelf/8a842ed755354b31e79214042a4a4695
Dagelf

Ceci est également réalisé avecvnstat -tr
St0rM

14

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 comme 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 comme 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 consulter ce site pour plus d'informations http://xmodulo.com/measure-packets-per-second-throughput-high-speed-network-interface.html


Ce n'est pas une solution réalisable pour "port spécifique ou application processID" car elle ne vous donne que le taux par interface.
Mene

6

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

ifstat

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


Merci pour ça. comment les autres se comportent-ils avec Mac? Je vais essayer d'installer ifstat et voir comment ça se passe. Quelques informations supplémentaires auraient certainement été utiles.
nyxee

3

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

Cela 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 puis divisés par 10 ^ 6 vous donneront des mégabits / seconde. Bien sûr, vous pouvez l'ajouter au script shell pour formater la sortie comme vous le souhaitez. Vous pouvez appeler cela avec le PID de votre application comme ça ./rt_traf.sh <PID>qui vous donnera une lecture instantanée de votre application depuis le démarrage. Pour regarder les statistiques en temps réel par seconde, vous pouvez encapsuler le script shell dans la commande watch:

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

le -n paramètre peut être ajusté jusqu'au dixième 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, les calculs peuvent être ajustés pour la taille / le temps dont vous avez besoin. Ce n'est pas la solution la plus élégante ou emballée sous film rétractable mais elle devrait fonctionner à la rigueur.


3
C'est faux. / proc / <PID> / net / netstat ne contient pas de données par processus.
nab

Pour développer le commentaire de nab: /proc/<pid>/net/netstatrenvoie les mêmes données que proc/net/netstat, ie. vous obtenez les mêmes données pour tous les processus.
EML

2

Je devais juste mesurer la quantité de trafic mysql entrant et sortant sur un ancien système où perl ne fonctionnait pas correctement, donc je n'ai pas pu résister à l'écriture de quelques lignes de awk qui servent le même objectif de mesurer le 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 monolignes, en voici une 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;}'

L' elseinstruction doit être supprimée, sinon les lignes seront ignorées et sumne seront pas précises. 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

Chaque application peut être effectuée avec une règle de pare-feu utilisant xtables et une modification de ce qui suit.

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

Vous trouverez ci-dessous un script qui fonctionne sur la plupart des routeurs Linux embarqués tels que ceux compatibles Ubiquiti et OpenWRT et obtient ses détails depuis / proc / net / dev.

(Et facile à changer en 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 simplement ce qui précède si vous avez besoin de le modifier - tous les routeurs intégrés n'ont pas d'éditeur! Assurez-vous de tout copier du # en haut au fait; au fond.

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

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


Veuillez ne pas poster la même réponse à plusieurs questions. Si la même information répond vraiment aux deux questions, alors une question (généralement la plus récente) doit être fermée en double de l'autre. Vous pouvez l'indiquer en votant pour le fermer comme doublon ou, si vous n'avez pas assez de réputation pour cela, lever un drapeau pour indiquer qu'il s'agit d'un doublon. Sinon, adaptez votre réponse à cette question et ne collez pas simplement la même réponse à plusieurs endroits.
DavidPostill

Vous avez posté exactement le même commentaire sur mon autre post ... qui a d'ailleurs été personnalisé ... Ce genre de réponse me fait juste me demander pourquoi j'ai pris le temps de contribuer ici.
Dagelf

S'il a été personnalisé, cela s'est produit après que les messages ont été marqués automatiquement par le système. Je n'ai pas le temps de lire chaque mot pour voir s'ils sont personnalisés ou non.
DavidPostill

1
La seule personnalisation que vous avez faite a été d'ajouter deux phrases au début de votre anser. Le reste semble identique. Et ces deux phrases n'étaient pas dans la réponse d'origine telle que publiée - c'est pourquoi elle a été automatiquement signalée comme une réponse en double.
DavidPostill
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.