Jak uzyskać statystyki sieci w czasie rzeczywistym w systemie Linux w formacie KB / MB / Bytes i dla określonego identyfikatora portu lub procesu?

22

Kiedyś IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Żadna z nich nie pomaga mi znaleźć pakietów w czasie rzeczywistym wysyłanych / odbieranych z mojej aplikacji w formacie KB lub MB. Powodem jest to, że piszę aplikację, w której muszę się upewnić, że moja kompresja jest poprawna, ale nie mogę przetestować, aby przejść dalej.

Czego mogę użyć do śledzenia bardzo konkretnych i dokładnych statystyk sieci w czasie rzeczywistym?

wprowadź opis zdjęcia tutaj

Mniam mniam mniam
źródło

Odpowiedzi:

27

Twoja aplikacja prawdopodobnie wysyła pakiety na określony numer portu UDP lub TCP lub na określony adres IP.

Dlatego możesz użyć czegoś takiego jak TCPdump do przechwytywania tego ruchu.

TCPdump nie daje ci statystyk w czasie rzeczywistym, których pragniesz, ale możesz podać dane wyjściowe do czegoś, co robi (postaram się zaktualizować tę odpowiedź odpowiedzią później).


Aktualizacja:

$ 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

Przerwałem to po minucie, naciskając Ctrl + C.

Trzeba dodać odpowiednie wyrażenie filtru na końcu tcpdumppolecenia, aby uwzględnić tylko ruch generowany przez aplikację (np. port 123)

Program netbpsjest następujący:

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

To tylko przykład, dostosuj się do smaku.

RedGrittyBrick
źródło
Wielkie dzięki, poczekam na twój działający przykład. Moim celem było to, co zrobiłem z $ bwm-ng -o zwykły -N -d, który pokazuje wyjście jako bit przez interfejsy, ale to się nie udaje, jeśli interfejs jest używany z wyjątkiem lo. Z drugiej strony IPtraf pokazuje doskonałe bajty w czasie rzeczywistym. Ale nie ma narzędzi, które mogłyby mi powiedzieć, jak bity i bajty w czasie rzeczywistym w RX / TX dla konkretnego interfejsu lub dowolnego interfejsu jako całości itp. Brakuje mi tego :-(
YumYumYum
@YumYum: odpowiedź zaktualizowana.
RedGrittyBrick 13.11.11
1
@RedGrittyBrick You absolutna legenda! Świetny skrypt! Dziękuję bardzo za udostępnienie. To odpowiada na moje pytanie na superuser.com/questions/395226/...
Eamorr
Ten powinien działać w boksie
Dagelf
Osiąga się to również przy pomocyvnstat -tr
St0rM
14

Użycie jak poniżej z tego samego folderu:

Aby sprawdzić program pakujący według interfejsu: ./netpps.sh eth0

Aby sprawdzić prędkość według interfejsu: ./netspeed.sh eth0

Zmierz liczbę pakietów na sekundę w interfejsie netpps.sh jako nazwę pliku

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

Zmierz przepustowość sieci na interfejsie netspeed.sh jako nazwę pliku

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

Proszę odnieść się do tej strony, aby uzyskać więcej informacji http://xmodulo.com/measure-packets-per-second-throughput-high-speed-network-interface.html

Muthukumar Anbalagan
źródło
Nie jest to wykonalne rozwiązanie dla „określonego identyfikatora portu lub procesu”, ponieważ podaje jedynie stawkę za interfejs.
Mene
6

Najłatwiejszy w użyciu i najłatwiejszy do kontrolowania danych wyjściowych i przekierowywania do pliku w celu ciągłego logowania:

ifstat

Prawdopodobnie pochodzi z większością dystrybucji Linuksa i może być zainstalowany wraz z brew na Macu

samthebest
źródło
Dziękuję za to. jak inni mogą sprzeciwić się Macowi? Spróbuję zainstalować ifstat i zobaczę, jak będzie. Przydałoby się trochę więcej informacji.
nyxee
3

Myślę, że możesz użyć interfejsu proc, aby uzyskać potrzebne informacje. Stworzyłem ten mały skrypt powłoki o nazwie rt_traf.sh:

#!/bin/bash

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

Spowoduje to wydrukowanie oktetów wejściowych i wyjściowych oddzielonych tabulatorami. Oktety pomnożone przez 8 dadzą Ci bity na sekundę, a następnie podzielone przez 10 ^ 6 dadzą Ci megabitów na sekundę. Oczywiście możesz dodać to do skryptu powłoki, aby sformatować dane wyjściowe tak, jak chcesz. Możesz to nazwać PID aplikacji w taki sposób, ./rt_traf.sh <PID>który zapewni natychmiastowy odczyt aplikacji od momentu uruchomienia. Aby oglądać statystyki w czasie rzeczywistym na sekundę, możesz zawinąć skrypt powłoki w komendę watch:

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

-nParametr może być regulowana przez całą drogę w dół do dziesiątych części sekundy. Aby wykonać obliczenia w czasie, zrobiłbym coś takiego:

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"

Ponownie matematyka może być dostosowana do potrzebnego rozmiaru / czasów. Nie jest to najbardziej eleganckie lub pakowane w folię termokurczliwą rozwiązanie, ale powinno działać w mgnieniu oka.

d34dh0r53
źródło
3
To jest źle. / proc / <PID> / net / netstat nie zawiera danych procesowych.
nab
Aby rozwinąć komentarz Naba: /proc/<pid>/net/netstatzwraca te same dane, co proc/net/netstatnp. otrzymujesz te same dane dla dowolnego / wszystkich procesów.
EML
2

Musiałem tylko zmierzyć, ile ruchu mysql wchodzi i wychodzi na starym systemie, w którym perl nie działa poprawnie, więc nie mogłem się powstrzymać przed napisaniem kilku wierszy awk, które służą temu samemu celowi mierzenia całkowitego ruchu widzianego przez 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

A jeśli bardziej Ci się podoba jedna linijka, oto jedna dla Ciebie:

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
źródło
elseOświadczenie powinno zostać usunięte inaczej linie zostaną pominięte i sumnie będą dokładne. 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

Dla każdej aplikacji można wykonać regułę zapory ogniowej za pomocą xtables i modyfikacji poniższych.

To nie odpowiada na pytanie „na aplikację”, ale tylko na „na interfejs”.

Poniżej znajduje się skrypt, który działa na większości wbudowanych routerów Linux, takich jak Ubiquiti i kompatybilnych z OpenWRT, i pobiera jego szczegóły z / proc / net / dev.

(I łatwo zmienić na pakiety itp.)

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

Skopiuj powyższe do schowka, a następnie w sesji terminalu na routerze:

$ cat > /tmp/n.sh

następnie: Ctrl + V (lub kliknij prawym przyciskiem myszy / Wklej)

następnie: Ctrl + D

$ chmod +x /tmp/n.sh

$ /tmp/n.sh eth0

Możesz także wkleić go do notatnika, a następnie powtórzyć powyższe, jeśli chcesz go edytować - nie wszystkie wbudowane routery mają edytor! Upewnij się, że skopiowałeś wszystko od # u góry po gotowe; na dnie.

Powyższy przykład netpps jest świetny BTW - ale nie wszystkie urządzenia mają zamontowany system plików / sys. Być może będziesz musiał zmienić / bin / bash na / bin / sh lub odwrotnie.

Źródło: https://gist.github.com/dagelf/ab2bad26ce96fa8d79b0834cd8cab549

Dagelf
źródło
Nie zamieszczaj tej samej odpowiedzi na wiele pytań. Jeśli ta sama informacja naprawdę odpowiada na oba pytania, to jedno pytanie (zwykle nowsze) powinno zostać zamknięte jako duplikat drugiego. Możesz to wskazać, głosując, aby zamknąć go jako duplikat lub, jeśli nie masz wystarczającej reputacji, podnieść flagę wskazującą, że jest to duplikat. W przeciwnym razie dostosuj swoją odpowiedź na to pytanie i nie wklejaj tej samej odpowiedzi w wielu miejscach.
DavidPostill
Opublikowałeś dokładnie ten sam komentarz do mojego drugiego postu ... który został przy okazji dostosowany ... Ten rodzaj odpowiedzi sprawia, że ​​zastanawiam się, dlaczego poświęciłem trochę czasu, aby się tutaj zgłosić.
Dagelf
Jeśli był dostosowany, to działo się to po tym, jak posty zostały automatycznie oznakowane przez system. Nie mam czasu czytać każdego słowa, aby sprawdzić, czy są one dostosowane, czy nie.
DavidPostill
1
Jedyne dostosowanie, jakie zrobiłeś, to dodać dwa zdania na początku ansera. Reszta wydaje się identyczna. Te dwa zdania nie były w pierwotnej odpowiedzi w formie, w jakiej zostały opublikowane - dlatego zostały automatycznie oznaczone jako duplikat odpowiedzi.
DavidPostill