¿Cómo debo determinar la utilización actual de la red?

9

Quiero mostrar la utilización de red actual (uso de ancho de banda) de una interfaz de un cuadro de Debian en un sitio web. No se supone que sea muy elaborado o preciso, solo un número simple como "52 Mbit / s".

Los monitores de ancho de banda de red típicos, como iftopno me dan forma de extraer simplemente dicho valor.

¿Cómo puedo recuperarlo mejor?

Por ejemplo, supongo que podría analizar /proc/net/devcada pocos minutos. Sin embargo, no estoy seguro de si esta es realmente la mejor manera de hacerlo.

Christoph Wurm
fuente

Respuestas:

10

Creo que ifstat te ayudará:

[root @ localhost ~] # ifstat -i eth0 -q 1 1
       eth0
 KB / s en KB / s fuera
 3390.26 69.69
migabi
fuente
7

La mejor manera de hacerlo simplemente es analizar /proc/net/dev(tenga en cuenta que /procno es portátil). Aquí hay un bashscript que preparé rápidamente que debería poder calcularlo:

#!/bin/bash

_die() {
    printf '%s\n' "$@"
    exit 1
}

_interface=$1

[[ ${_interface} ]] || _die 'Usage: ifspeed [interface]'
grep -q "^ *${_interface}:" /proc/net/dev || _die "Interface ${_interface} not found in /proc/net/dev"

_interface_bytes_in_old=$(awk "/^ *${_interface}:/"' { if ($1 ~ /.*:[0-9][0-9]*/) { sub(/^.*:/, "") ; print $1 } else { print $2 } }' /proc/net/dev)
_interface_bytes_out_old=$(awk "/^ *${_interface}:/"' { if ($1 ~ /.*:[0-9][0-9]*/) { print $9 } else { print $10 } }' /proc/net/dev)

while sleep 1; do
    _interface_bytes_in_new=$(awk "/^ *${_interface}:/"' { if ($1 ~ /.*:[0-9][0-9]*/) { sub(/^.*:/, "") ; print $1 } else { print $2 } }' /proc/net/dev)
    _interface_bytes_out_new=$(awk "/^ *${_interface}:/"' { if ($1 ~ /.*:[0-9][0-9]*/) { print $9 } else { print $10 } }' /proc/net/dev)

    printf '%s: %s\n' 'Bytes in/sec'  "$(( _interface_bytes_in_new - _interface_bytes_in_old ))" \
                      'Bytes out/sec' "$(( _interface_bytes_out_new - _interface_bytes_out_old ))"

    # printf '%s: %s\n' 'Kilobytes in/sec'  "$(( ( _interface_bytes_in_new - _interface_bytes_in_old ) / 1024 ))" \
    #                   'Kilobytes out/sec' "$(( ( _interface_bytes_out_new - _interface_bytes_out_old ) / 1024 ))"

    # printf '%s: %s\n' 'Megabits in/sec'  "$(( ( _interface_bytes_in_new - _interface_bytes_in_old ) / 131072 ))" \
    #                   'Megabits out/sec' "$(( ( _interface_bytes_out_new - _interface_bytes_out_old ) / 131072 ))"

    _interface_bytes_in_old=${_interface_bytes_in_new}
    _interface_bytes_out_old=${_interface_bytes_out_new}
done

Tenga en cuenta que sleepno considera la cantidad de tiempo que lleva realizar las operaciones en el ciclo while, por lo que esto es (muy levemente) inexacto. En mi mina de cobre de 600 mhz, el ciclo tarda 0.011 segundos, una inexactitud insignificante para la mayoría de los propósitos. Tenga en cuenta también que cuando utiliza las salidas de kilobyte / megabit (comentadas), bash solo comprende la aritmética de enteros.

Chris Down
fuente
Creo que esta debería ser la respuesta elegida. Todas las demás soluciones se transmiten, detrás de escena, al análisis /proc/net/dev, sin comprender realmente qué y cómo sucede esta magia.
Eran
Esta solución funcionó para mí en un enrutador / busybox.
cloneman
Utilícelo date +%s.%Npara obtener la marca de tiempo de Unix para cada iteración y divida la diferencia de bytes por la diferencia de marca de tiempo. Luego, evita el problema de que las iteraciones de bucle sean más largas que 1s.
Arnavion
3

Hay monitores de tráfico de red como vnstat que mantiene registros mensuales de su tráfico, o slurm que toma sus valores directamente de los almacenados en el núcleo. Está disponible en la mayoría de los repositorios de distro.

Esto es lo que veo cuando corro slurm -i ra0:

ingrese la descripción de la imagen aquí

invertir
fuente
1

Aquí hay un script de shell muy simple para calcular esto:

#!/bin/sh

dev=$1

grep -q "^$dev:" /proc/net/dev || exec echo "$dev: no such device"

read rx <"/sys/class/net/$dev/statistics/rx_bytes"
read tx <"/sys/class/net/$dev/statistics/tx_bytes"

while sleep 1; do
    read newrx <"/sys/class/net/$dev/statistics/rx_bytes"
    read newtx <"/sys/class/net/$dev/statistics/tx_bytes"

    # convert bytes to kbit/s: bytes * 8 / 1000 => bytes / 125
    echo "$dev  {rx: $(((newrx-rx) / 125)), tx: $(((newtx-tx) / 125))}"

    rx=$newrx
    tx=$newtx
done

simplemente inicie el script pasando el nombre de la interfaz, por ejemplo. ./shtraf eth1

teknoraver
fuente
1
¿Puedes explicar esto un poco? ¿Cuál debe ser exactamente el parámetro? ¿Cuál es el significado de 125? Por favor no responda en los comentarios; edite su respuesta para que sea más clara y completa.
Scott