¿Cómo obtener estadísticas de red en tiempo real en Linux con formato KB / MB / Bytes y para el puerto específico o el ID de proceso de la aplicación?

22

Solía IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Ninguno de ellos me está ayudando a encontrar paquetes en tiempo real que se envían / ​​reciben desde mi aplicación en formato KB o MB. La razón es que estoy escribiendo una aplicación, donde necesito estar muy seguro de que mi compresión es correcta, pero no puedo probar para avanzar.

¿Qué puedo usar para rastrear estadísticas de red en tiempo real muy específicas y precisas?

ingrese la descripción de la imagen aquí

Yum Yum Yum
fuente

Respuestas:

27

Su aplicación probablemente esté enviando paquetes a un número de puerto UDP o TCP específico o a una dirección IP específica.

Por lo tanto, puede usar algo como TCPdump para capturar ese tráfico.

TCPdump no le brinda las estadísticas en tiempo real que desea, pero puede alimentar su salida a algo que sí lo haga (intentaré actualizar esta respuesta con una respuesta más adelante).


Actualizar:

$ 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

Lo interrumpí después de un minuto presionando Ctrl + C.

Debería agregar una expresión de filtro adecuada al final del tcpdumpcomando para incluir solo el tráfico generado por su aplicación (por ejemplo port 123)

El programa netbpses este:

#!/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 solo un ejemplo, ajustarse al gusto.

RedGrittyBrick
fuente
Muchas gracias, esperaré tu ejemplo de trabajo. Mi objetivo era como lo hice con $ bwm-ng -o plain -N -d que muestra la salida como bit por las interfaces pero falla si la interfaz se usa excepto lo. Por otro lado, el IPtraf muestra excelentes bytes en tiempo real. Pero no hay herramientas que me puedan decir como bits y bytes en tiempo real en RX / TX para una interfaz específica o cualquier interfaz como total, etc. Me falta :-(
YumYumYum
@YumYum: respuesta actualizada.
RedGrittyBrick
1
@RedGrittyBrick ¡Leyenda absoluta! Gran guión! Muchas gracias por compartir. Esto responde a mi pregunta en superuser.com/questions/395226/...
Eamorr
Este debería funcionar en busybox bash en enrutadores integrados: gist.github.com/dagelf/8a842ed755354b31e79214042a4a4695
Dagelf
Esto también se logra convnstat -tr
St0rM
14

Uso como abajo de la misma carpeta:

Para verificar el empaquetador por interfaz: ./netpps.sh eth0

Para verificar la velocidad por interfaz: ./netspeed.sh eth0

Medir paquetes por segundo en una interfaz netpps.sh como nombre de archivo

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

Mida el ancho de banda de red en una interfaz netspeed.sh como nombre de archivo

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

Consulte este sitio para obtener más información http://xmodulo.com/measure-packets-per-second-throughput-high-speed-network-interface.html

Muthukumar Anbalagan
fuente
Esta no es una solución factible para un "puerto específico o ID de proceso de aplicación", ya que solo le proporciona la velocidad por interfaz.
Mene
6

Más fácil de usar y más fácil de controlar la salida y redirigir al archivo para el registro continuo:

ifstat

Probablemente viene con la mayoría de las distribuciones de Linux, y se puede instalar con brew en mac

samthebest
fuente
gracias por eso. ¿Cómo se justifican los demás con Mac? Intentaré instalar ifstat y ver cómo funciona. Alguna información más definitivamente habría sido útil.
nyxee
3

Creo que puede usar la interfaz de proceso para obtener la información que necesita. Creé este pequeño script de shell llamado rt_traf.sh:

#!/bin/bash

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

Esto imprimirá los octetos de entrada y salida separados por una pestaña. Los octetos multiplicados por 8 te darán bits / segundo y luego divididos entre 10 ^ 6 te darán megabits / segundo. Por supuesto, puede agregar esto al script de shell para formatear la salida como desee. Puede llamar a esto con el PID de su aplicación, lo ./rt_traf.sh <PID>que le dará una lectura instantánea de su aplicación desde el inicio. Para ver estadísticas en tiempo real por segundo, puede ajustar el script de shell en el comando watch:

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

El -nparámetro se puede ajustar hasta décimas de segundo. Para hacer un cálculo a lo largo del tiempo, haría algo como esto:

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"

Una vez más, las matemáticas se pueden ajustar para el tamaño / veces que necesita. No es la solución más elegante o envuelta por contracción, pero debería funcionar en un apuro.

d34dh0r53
fuente
3
Esto está mal. / proc / <PID> / net / netstat no contiene datos por proceso.
Nab
Para ampliar el comentario de nab: /proc/<pid>/net/netstatdevuelve los mismos datos que proc/net/netstat, es decir. obtienes los mismos datos para cualquiera / todos los procesos.
EML
2

Solo necesitaba medir cuánto tráfico mysql entra y sale en un sistema antiguo donde Perl no funcionaba correctamente, por lo que no pude resistirme a escribir algunas líneas de awk que sirvan para el mismo objetivo de medir el tráfico total visto por 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

Y si te gustan más las frases sencillas, aquí tienes una:

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
fuente
La elsedeclaración debe eliminarse; de ​​lo contrario, se omitirán las líneas y sumno serán precisas. 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

Por aplicación se puede hacer con una regla de firewall usando xtables y una modificación de lo siguiente.

Esto no responde la pregunta "por aplicación" sino solo la pregunta "por interfaz".

A continuación se muestra un script que funciona en la mayoría de los enrutadores Linux integrados, como Ubiquiti y OpenWRT, y obtiene sus detalles de / proc / net / dev.

(Y fácil de cambiar a paquetes, 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;

Copie lo anterior en su portapapeles y luego en una sesión de terminal en su enrutador:

$ cat > /tmp/n.sh

luego: Ctrl + V (o clic derecho / Pegar)

entonces: Ctrl + D

$ chmod +x /tmp/n.sh

$ /tmp/n.sh eth0

También puede pegarlo en un bloc de notas, luego repita lo anterior si necesita editarlo: ¡no todos los enrutadores integrados tienen un editor! Asegúrese de copiar todo, desde el # en la parte superior hasta el hecho; en el fondo.

El ejemplo de netpps anterior es genial, por cierto, pero no todos los dispositivos tienen un sistema de archivos montado / sys. También es posible que deba cambiar / bin / bash a / bin / sh o viceversa.

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

Dagelf
fuente
No publique la misma respuesta a varias preguntas. Si la misma información realmente responde a ambas preguntas, entonces una pregunta (generalmente la más nueva) debería cerrarse como un duplicado de la otra. Puede indicar esto votando para cerrarlo como un duplicado o, si no tiene suficiente reputación para eso, levante una bandera para indicar que es un duplicado. De lo contrario, adapte su respuesta a esta pregunta y no solo pegue la misma respuesta en varios lugares.
DavidPostill
Publicaste exactamente el mismo comentario en mi otra publicación ... que fue incidentalmente personalizada ... Este tipo de respuesta me hace preguntarme por qué me tomé el tiempo para contribuir aquí.
Dagelf
Si fue personalizado, eso sucedió después de que las publicaciones fueron autorreguladas por el sistema. No tengo tiempo para leer cada palabra para ver si están personalizadas o no.
DavidPostill
1
La única personalización que hizo fue agregar dos oraciones al comienzo de su respuesta. El resto parece idéntico. Y esas dos oraciones no estaban en la respuesta original como se publicó, por lo que se marcó automáticamente como una respuesta duplicada.
DavidPostill