Come devo determinare l'attuale utilizzo della rete?


9

Voglio mostrare l'attuale utilizzo della rete (utilizzo della larghezza di banda) di un'interfaccia di un box Debian su un sito web. Non dovrebbe essere molto elaborato o preciso, ma solo un numero semplice come "52 Mbit / s".

I tipici monitor di larghezza di banda di rete come iftopnon mi danno modo di estrarre semplicemente un tale valore.

Come posso recuperarlo al meglio?

Ad esempio, immagino di poter analizzare /proc/net/devogni pochi minuti. Non sono sicuro se questo sia davvero il modo migliore per farlo.

Risposte:


10

Penso che ifstat ti aiuterà:

[root @ localhost ~] # ifstat -i eth0 -q 1 1
       eth0
 KB / s in KB / s in uscita
 3390.26 69.69

7

Il modo migliore per farlo è probabilmente quello di analizzare /proc/net/dev(attenzione che /procnon è portatile). Ecco uno bashscript che ho rapidamente messo insieme che dovrebbe essere in grado di calcolarlo:

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

Tieni presente che sleepnon considera il tempo necessario per eseguire le operazioni nel ciclo while, quindi questo è (molto leggermente) inaccurato. Sul mio coppermine da 600 mhz, il loop impiega 0,011 secondi, un'imprecisione trascurabile per la maggior parte degli scopi. Ricorda anche quando usi le uscite (commentate) in kilobyte / megabit, bash capisce solo l'aritmetica dei numeri interi.


Penso che questa dovrebbe essere la risposta scelta. Ogni altra soluzione si basa, dietro le quinte, sull'analisi /proc/net/dev, senza realmente capire cosa e come accade questa magia.
Eran,

Questa soluzione ha funzionato per me su un router / busybox.
cloneman,

Utilizzare date +%s.%Nper ottenere il timestamp unix per ogni iterazione e dividere la differenza di byte per la differenza di timestamp. Quindi eviti che il problema delle iterazioni di loop sia più lungo di 1 secondo.
Arnavion,

3

Esistono monitor di traffico di rete come vnstat che tiene registri mensili del tuo traffico, o slurm che prende i suoi valori direttamente da quelli memorizzati nel kernel. È disponibile nella maggior parte dei repository distro.

Ecco cosa vedo quando corro slurm -i ra0:

inserisci qui la descrizione dell'immagine


1

Ecco uno script di shell molto semplice per calcolare questo:

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

basta avviare lo script passando il nome dell'interfaccia, ad es. ./shtraf eth1


1
Puoi spiegarlo un po '? Esattamente quale dovrebbe essere il parametro? Qual è il significato di 125? Si prega di non rispondere nei commenti; modifica la tua risposta per renderla più chiara e completa.
Scott,
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.