Як я можу визначити поточне використання мережі?


9

Я хочу відобразити поточне використання мережі (використання пропускної здатності) одного інтерфейсу вікна Debian на веб-сайті. Це не повинно бути дуже детальним або точним, просто просте число, наприклад "52 Мбіт / с".

Типові мережеві монітори пропускної здатності, такі як, не iftopдають мені можливості просто отримати таке значення.

Як я можу найкраще її отримати?

Наприклад, я думаю, що я можу проаналізувати /proc/net/devкожні кілька хвилин. Не впевнений, чи справді це найкращий спосіб зробити це.

Відповіді:


10

Я думаю, що ifstat допоможе вам:

[root @ localhost ~] # ifstat -i eth0 -q 1 1
       eth0
 Кб / с у кб / с вихід
 3390,26 69,69

7

Найкращий спосіб зробити це просто, мабуть, проаналізувати /proc/net/dev(попередити, що /procце не портативний). Ось bashсценарій, який я швидко зібрав, який повинен мати можливість його обчислити:

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

Майте на увазі, що sleepне враховуйте кількість часу, необхідного для виконання операцій в циклі "час", тому це (дуже незначно) неточно. На моїй мідній шахті 600 МГц цикл займає 0,011 секунди - це незначна неточність для більшості цілей. Майте на увазі також, використовуючи (коментований) кілобайт / мегабітний вихід, bash розуміє лише цілу арифметику.


Я думаю, що це повинна бути обрана відповідь. Кожне інше рішення ретрансляється поза кадром, /proc/net/devрозбираючи, насправді не розуміючи, що і як відбувається ця магія.
Еран

Це рішення працювало для мене на маршрутизаторі / busbox.
клоніст

Використовуйте date +%s.%Nдля отримання часової позначки unix для кожної ітерації та розділіть різницю байтів на різницю часових позначок. Тоді ви уникаєте, щоб проблема ітерацій циклу була довшою 1 секунди.
Арнавіон

3

Існують монітори мережевого трафіку, такі як vnstat, який щомісяця веде облік вашого трафіку або slurm, який приймає його значення безпосередньо з тих, що зберігаються в ядрі. Він доступний у більшості репостів дистрибуції.

Ось що я бачу, коли бігаю slurm -i ra0:

введіть тут опис зображення


1

Ось дуже простий скрипт оболонки для обчислення цього:

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

просто запустіть сценарій, передаючи ім'я інтерфейсу, наприклад. ./shtraf eth1


1
Чи можете ви це трохи пояснити? Яким саме повинен бути параметр? Яке значення має 125? Будь ласка, не відповідайте на коментарі; відредагуйте свою відповідь, щоб зробити її більш зрозумілою та повною.
Скотт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.