Wie soll ich die aktuelle Netzwerkauslastung ermitteln?

9

Ich möchte die aktuelle Netzwerkauslastung (Bandbreitennutzung) einer Schnittstelle einer Debian-Box auf einer Website anzeigen. Es soll nicht sehr ausführlich oder präzise sein, nur eine einfache Zahl wie "52 Mbit / s".

Typische Netzwerkbandbreitenmonitore wie z. B. iftopgeben mir keine Möglichkeit, einen solchen Wert einfach zu extrahieren.

Wie kann ich es am besten abrufen?

Zum Beispiel könnte ich /proc/net/devalle paar Minuten analysieren . Ich bin mir nicht sicher, ob dies wirklich der beste Weg ist, dies zu tun.

Christoph Wurm
quelle

Antworten:

10

Ich denke, ifstat wird Ihnen helfen:

[root @ localhost ~] # ifstat -i eth0 -q 1 1
       eth0
 KB / s in KB / s aus
 3390,26 69,69
Migabi
quelle
7

Der beste Weg, dies einfach zu tun, ist wahrscheinlich das Parsen /proc/net/dev(seien Sie gewarnt, dass /proces nicht portabel ist). Hier ist ein bashSkript, das ich schnell zusammengestellt habe und das es berechnen kann:

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

Beachten Sie, dass sleepdie Zeit, die für die Ausführung der Operationen in der while-Schleife benötigt wird, nicht berücksichtigt wird. Dies ist also (sehr geringfügig) ungenau. Bei meiner 600-MHz-Coppermine dauert die Schleife 0,011 Sekunden - eine vernachlässigbare Ungenauigkeit für die meisten Zwecke. Beachten Sie auch, dass bash bei Verwendung der (auskommentierten) Kilobyte / Megabit-Ausgänge nur die Ganzzahlarithmetik versteht.

Chris Down
quelle
Ich denke, dass dies die gewählte Antwort sein sollte. Jede andere Lösung setzt hinter den Kulissen auf das Parsen /proc/net/dev, ohne wirklich zu verstehen, was und wie diese Magie geschieht.
Eran
Diese Lösung funktionierte für mich auf einem Router / einer Busybox.
Cloneman
Verwenden Sie date +%s.%Ndiese Option, um den Unix-Zeitstempel für jede Iteration abzurufen und die Byte-Differenz durch die Zeitstempeldifferenz zu dividieren. Dann vermeiden Sie das Problem, dass Schleifeniterationen länger als 1s sind.
Arnavion
3

Es gibt Netzwerkverkehrsmonitore wie vnstat , die monatliche Aufzeichnungen Ihres Datenverkehrs führen, oder Slurm, der seine Werte direkt von den im Kernel gespeicherten Werten übernimmt. Es ist in den meisten Distributionen erhältlich.

Folgendes sehe ich, wenn ich renne slurm -i ra0:

Geben Sie hier die Bildbeschreibung ein

umkehren
quelle
1

Hier ist ein sehr einfaches Shell-Skript, um dies zu berechnen:

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

Starten Sie einfach das Skript, indem Sie den Schnittstellennamen übergeben, z. ./shtraf eth1

Teknoraver
quelle
1
Können Sie das ein wenig erklären? Was genau soll der Parameter sein? Welche Bedeutung hat das 125? Bitte antworten Sie nicht in Kommentaren; Bearbeiten Sie Ihre Antwort, um sie klarer und vollständiger zu gestalten.
Scott