Как мне определить текущее использование сети?


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не учитывается количество времени, необходимое для выполнения операций в цикле while, так что это (очень немного) неточно. На моем медном руднике с частотой 600 МГц цикл занимает 0,011 секунды - незначительная погрешность для большинства целей. Помните также, что при использовании (закомментированных) выходных данных в килобайтах / мегабитах bash понимает только целочисленную арифметику.


Я думаю, что это должен быть выбранный ответ. Любое другое решение закулисно опирается на анализ /proc/net/dev, фактически не понимая, что и как происходит это волшебство.
Эран

У меня это решение работало на роутере / busybox.
клонист

Используйте date +%s.%Nдля получения метки времени Unix для каждой итерации и делите разницу байтов на разницу меток времени. Тогда вы избежите проблемы длинных итераций цикла.
Арнавион

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.