Jak określić bieżące wykorzystanie sieci?

9

Chcę wyświetlić bieżące wykorzystanie sieci (wykorzystanie przepustowości) jednego interfejsu skrzynki Debian na stronie internetowej. Nie powinna być bardzo skomplikowana ani precyzyjna, wystarczy zwykła liczba, taka jak „52 Mbit / s”.

Typowe monitory przepustowości sieci, takie jak nie iftoppozwalają mi po prostu wyodrębnić takiej wartości.

Jak mogę go najlepiej odzyskać?

Na przykład myślę, że mogę analizować /proc/net/devco kilka minut. Nie jestem jednak pewien, czy to naprawdę najlepszy sposób na zrobienie tego.

Christoph Wurm
źródło

Odpowiedzi:

10

Myślę, że ifstat pomoże ci:

[root @ localhost ~] # ifstat -i eth0 -q 1 1
       eth0
 KB / s na KB / s na zewnątrz
 3390,26 69,69
migabi
źródło
7

Najlepszym sposobem na to jest po prostu parsowanie /proc/net/dev(należy pamiętać, że /procnie jest przenośne). Oto bashskrypt, który szybko przygotowałem, który powinien być w stanie go obliczyć:

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

Pamiętaj, że sleepnie bierze pod uwagę czasu potrzebnego na wykonanie operacji w pętli while, więc jest to (bardzo nieznacznie) niedokładne. Na mojej coppermine o częstotliwości 600 MHz pętla zajmuje 0,011 sekundy - w większości przypadków jest to nieistotna niedokładność. Pamiętaj także, że używając (skomentowane) wyjścia kilobajt / megabit, bash rozumie tylko arytmetykę liczb całkowitych.

Chris Down
źródło
Myślę, że to powinna być wybrana odpowiedź. Każde inne rozwiązanie przekazuje, za kulisami, parsowanie /proc/net/dev, bez faktycznego zrozumienia, co i jak ta magia się dzieje.
Eran
To rozwiązanie działało dla mnie na routerze / busyboksie.
kloneman
Użyj, date +%s.%Naby uzyskać uniksowy znacznik czasu dla każdej iteracji i podzielić różnicę bajtów przez różnicę znacznika czasu. W ten sposób unikniesz problemu, że iteracje pętli są dłuższe niż 1s.
Arnavion,
3

Istnieją monitory ruchu sieciowego, takie jak vnstat, który prowadzi miesięczne zapisy twojego ruchu, lub slurm, który pobiera jego wartości bezpośrednio z tych przechowywanych w jądrze. Jest dostępny w większości repozytoriów dystrybucji.

Oto, co widzę po uruchomieniu slurm -i ra0:

wprowadź opis zdjęcia tutaj

odwracać
źródło
1

Oto bardzo prosty skrypt powłoki, aby to obliczyć:

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

po prostu uruchom skrypt przekazując nazwę interfejsu, np. ./shtraf eth1

teknoraver
źródło
1
Czy możesz to trochę wyjaśnić? Dokładnie jaki powinien być parametr? Jakie jest znaczenie 125? Proszę nie odpowiadać w komentarzach; edytuj swoją odpowiedź, aby była jaśniejsza i bardziej kompletna.
Scott