Bagaimana saya harus menentukan pemanfaatan jaringan saat ini?

9

Saya ingin menampilkan pemanfaatan jaringan saat ini (penggunaan bandwidth) dari satu antarmuka kotak Debian di situs web. Itu tidak seharusnya sangat rumit atau tepat, hanya angka sederhana seperti "52 Mbit / s".

Monitor bandwidth jaringan yang umum seperti iftopmemberi saya cara untuk mengekstraksi nilai semacam itu.

Bagaimana cara terbaik mengambilnya?

Misalnya, saya kira saya mungkin menguraikan /proc/net/devsetiap beberapa menit. Tidak yakin apakah ini benar-benar cara terbaik untuk melakukan ini.

Christoph Wurm
sumber

Jawaban:

10

Saya pikir ifstat akan membantu Anda:

[root @ localhost ~] # ifstat -i eth0 -q 1 1
       eth0
 KB / s dalam KB / s out
 3390.26 69.69
migabi
sumber
7

Cara terbaik untuk melakukannya adalah dengan menguraikan /proc/net/dev(diperingatkan bahwa /procini tidak portabel). Berikut ini bashskrip yang saya buat dengan cepat yang seharusnya dapat menghitungnya:

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

Ingatlah bahwa sleeptidak mempertimbangkan jumlah waktu yang diperlukan untuk melakukan operasi di loop sementara, jadi ini (sangat sedikit) tidak akurat. Pada tambang tembaga 600mhz saya, loop membutuhkan waktu 0,011 detik - ketidaktepatan yang dapat diabaikan untuk sebagian besar tujuan. Ingat juga ketika menggunakan output (dikomentari) kilobyte / megabit, bash hanya memahami aritmatika integer.

Chris Down
sumber
Saya pikir ini harus menjadi jawaban yang dipilih. Setiap solusi lain menyampaikan, di belakang layar, tentang penguraian /proc/net/dev, tanpa benar-benar memahami apa dan bagaimana keajaiban ini terjadi.
Eran
Solusi ini bekerja untuk saya di router / busybox.
cloneman
Gunakan date +%s.%Nuntuk mendapatkan cap waktu unix untuk setiap iterasi dan bagi perbedaan byte dengan perbedaan cap waktu. Maka Anda menghindari masalah iterasi loop lebih dari 1s.
Arnavion
3

Ada monitor lalu lintas jaringan seperti vnstat yang menyimpan catatan lalu lintas bulanan Anda, atau slurm yang mengambil nilainya langsung dari yang disimpan di kernel. Ini tersedia di sebagian besar repo distro.

Inilah yang saya lihat ketika saya berlari slurm -i ra0:

masukkan deskripsi gambar di sini

membalikkan
sumber
1

Berikut ini adalah skrip shell yang sangat sederhana untuk menghitung ini:

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

mulai saja skrip yang melewati nama antarmuka, mis. ./shtraf eth1

teknoraver
sumber
1
Bisakah Anda menjelaskan ini sedikit? Apa yang seharusnya menjadi parameter? Apa pentingnya 125? Tolong jangan menanggapi dalam komentar; edit jawaban Anda untuk membuatnya lebih jelas dan lebih lengkap.
Scott