Come ottenere statistiche di rete in tempo reale su Linux con formato KB / MB / byte e per ID porta o applicazione specifici?


22

Ho usato IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Nessuno di loro mi sta aiutando a trovare pacchetti in tempo reale inviati / ricevuti dalla mia applicazione in formato KB o MB. Il motivo è che sto scrivendo un'applicazione, in cui devo essere molto sicuro che la mia compressione sia corretta, ma non riesco a eseguire il test per andare avanti.

Cosa posso usare per tracciare statistiche di rete in tempo reale molto specifiche e precise?

inserisci qui la descrizione dell'immagine

Risposte:


27

La tua applicazione sta probabilmente inviando pacchetti a un numero di porta UDP o TCP specifico o a un indirizzo IP specifico.

È quindi possibile utilizzare qualcosa come TCPdump per acquisire quel traffico.

TCPdump non ti fornisce le statistiche in tempo reale che desideri, ma puoi alimentare l'output in qualcosa che lo fa (proverò ad aggiornare questa risposta con una risposta in seguito).


Aggiornare:

$ 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

L'ho interrotto dopo un minuto premendo Ctrl + C.

Dovresti aggiungere un'espressione di filtro adatta alla fine del tcpdumpcomando per includere solo il traffico generato dalla tua app (ad es. port 123)

Il programma netbpsè questo:

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

È solo un esempio, aggiusta il gusto.


Molte grazie, aspetterò il tuo esempio di lavoro. Il mio obiettivo era come ho fatto con $ bwm-ng -o plain -N -d che mostra l'output come bit dalle interfacce ma che fallisce se l'interfaccia viene utilizzata tranne lo. D'altra parte, IPtraf mostra eccellenti byte in tempo reale. Ma non ci sono strumenti che possono dirmi bit e byte in tempo reale in RX / TX per un'interfaccia specifica o qualsiasi interfaccia come totale ecc. Mi manca :-(
YumYumYum

@YumYum: risposta aggiornata.
RedGrittyBrick

1
@RedGrittyBrick La tua leggenda assoluta! Ottima sceneggiatura! Grazie mille per la condivisione. Questo risponde alla mia domanda su superuser.com/questions/395226/…
Eamorr

Questo dovrebbe funzionare in modalità trafficata su router embedded: gist.github.com/dagelf/8a842ed755354b31e79214042a4a4695
Dagelf

Ciò si ottiene anche convnstat -tr
St0rM,

14

Utilizzo come di seguito dalla stessa cartella:

Per controllare il packer per interfaccia: ./netpps.sh eth0

Per verificare la velocità per interfaccia: ./netspeed.sh eth0

Misura i pacchetti al secondo su un'interfaccia netpps.sh come nome file

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

Misura la larghezza di banda della rete su un'interfaccia netspeed.sh come nome file

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

Per maggiori informazioni consultare questo sito http://xmodulo.com/measure-packets-per-second-throughput-high-speed-network-interface.html


Questa non è una soluzione fattibile per "portID specifico o application processID" in quanto fornisce solo la tariffa per interfaccia.
Mene,

6

Più facile da usare e più semplice per controllare l'output e reindirizzare al file per la registrazione continua:

ifstat

Probabilmente viene fornito con la maggior parte delle distribuzioni di Linux e può essere installato con brew su mac


grazie per quello. come si comportano gli altri con il Mac? Proverò a installare ifstat e vedrò come va. Qualche informazione in più sarebbe sicuramente stata utile.
Nyxee,

3

Penso che tu possa usare l'interfaccia proc per ottenere le informazioni di cui hai bisogno. Ho creato questo piccolo script di shell chiamato rt_traf.sh:

#!/bin/bash

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

Ciò stamperà gli ottetti in e out separati da una scheda. Gli ottetti moltiplicati per 8 ti daranno bit / secondo e poi divisi per 10 ^ 6 ti daranno megabit / secondo. Ovviamente puoi aggiungerlo allo script della shell per formattare l'output come lo desideri. Puoi chiamarlo con il PID della tua applicazione in questo modo, ./rt_traf.sh <PID>che ti darà una lettura istantanea della tua applicazione dall'avvio. Per guardare le statistiche in tempo reale al secondo è possibile racchiudere lo script della shell nel comando watch:

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

Il -nparametro può essere regolato fino a decimi di secondo. Per fare un calcolo nel tempo, farei qualcosa del genere:

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"

Ancora una volta la matematica può essere regolata per le dimensioni / i tempi necessari. Non è la soluzione più elegante o termoretraibile ma dovrebbe funzionare in un pizzico.


3
Questo è sbagliato. / proc / <PID> / net / netstat non contiene dati per processo.
nab

Per espandere il commento di nab: /proc/<pid>/net/netstatrestituisce gli stessi dati di proc/net/netstat, ad es. ottieni gli stessi dati per qualsiasi / tutti i processi.
EML

2

Avevo solo bisogno di misurare la quantità di traffico mysql in entrata e in uscita su un vecchio sistema in cui il perl non funzionava correttamente, quindi non ho resistito alla scrittura di poche righe di awk che hanno lo stesso obiettivo di misurare il traffico totale visto da 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

E se ti piacciono i one-liner meglio, eccone uno per te:

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' elseistruzione deve essere rimossa altrimenti le righe verranno ignorate e sumnon saranno accurate. 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

Per ogni applicazione si può fare una regola firewall usando xtables e una modifica di seguito.

Questo non risponde alla domanda "per applicazione" ma solo a quella "per interfaccia".

Di seguito è riportato uno script che funziona sulla maggior parte dei router Linux integrati come quelli compatibili con Ubiquiti e OpenWRT e ottiene i suoi dettagli da / proc / net / dev.

(E facile da cambiare in pacchetti ecc.)

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

Copia quanto sopra negli appunti e poi in una sessione terminale sul router:

$ cat > /tmp/n.sh

quindi: Ctrl + V (o tasto destro / Incolla)

quindi: Ctrl + D

$ chmod +x /tmp/n.sh

$ /tmp/n.sh eth0

Puoi anche incollarlo in un blocco note, quindi ripetere quanto sopra se è necessario modificarlo - non tutti i router integrati hanno un editor! Assicurati di copiare tutto da # in alto a fatto; in fondo.

L'esempio di netpps sopra è ottimo BTW - ma non tutti i dispositivi hanno un filesystem montato / sys. Potrebbe anche essere necessario modificare / bin / bash in / bin / sh o viceversa.

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


Si prega di non pubblicare la stessa risposta a più domande. Se le stesse informazioni rispondono davvero ad entrambe le domande, allora una domanda (di solito la più recente) dovrebbe essere chiusa come duplicata dell'altra. Puoi indicarlo votando per chiuderlo come duplicato o, se non hai abbastanza reputazione per quello, alza una bandiera per indicare che è un duplicato. Altrimenti personalizza la tua risposta a questa domanda e non incollare la stessa risposta in più punti.
DavidPostill

Hai pubblicato esattamente lo stesso commento sul mio altro post ... che è stato per caso personalizzato ... Questo tipo di risposta mi fa solo chiedere perché mi sono preso il tempo di contribuire qui.
Dagelf,

Se è stato personalizzato, ciò è accaduto dopo che i post sono stati contrassegnati automaticamente dal sistema. Non ho tempo di leggere ogni parola per vedere se sono personalizzate o meno.
DavidPostill

1
L'unica personalizzazione che hai fatto è stata aggiungere due frasi all'inizio della tua risposta. Il resto sembra identico. E quelle due frasi non erano nella risposta originale come postata, motivo per cui è stata automaticamente contrassegnata come risposta duplicata.
DavidPostill
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.