Как получить сетевую статистику в реальном времени в Linux в формате KB / MB / Bytes и для определенного порта или идентификатора процесса приложения?

22

Я IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Ни один из них не помогает мне находить пакеты в реальном времени, которые отправляются / принимаются из моего приложения в формате КБ или МБ. Причина в том, что я пишу приложение, в котором я должен быть уверен, что мое сжатие правильное, но я не могу проверить движение вперед.

Что я могу использовать для отслеживания очень точной и точной статистики сети в реальном времени?

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

YumYumYum
источник

Ответы:

27

Ваше приложение, вероятно, отправляет пакеты на определенный номер порта UDP или TCP или на определенный IP-адрес.

Поэтому вы можете использовать что-то вроде TCPdump для захвата этого трафика.

TCPdump не дает вам желаемую статистику в реальном времени, но вы можете передать ее вывод чему-то, что делает (я постараюсь обновить этот ответ ответом позже).


Обновить:

$ sudo tcpdump -i eth1 -l -e -n | ./netbps
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
11:36:53    2143.33 Bps
11:37:03    1995.99 Bps
11:37:13    2008.35 Bps
11:37:23    1999.97 Bps
11:37:33    2083.32 Bps
131 packets captured
131 packets received by filter
0 packets dropped by kernel

Я прервал это через минуту, нажав Ctrl + C.

Вам нужно добавить подходящее выражение фильтра в конце tcpdumpкоманды, чтобы включить только трафик, генерируемый вашим приложением (например port 123)

Программа netbpsтакая:

#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes;

my $reporting_interval = 10.0; # seconds
my $bytes_this_interval = 0;
my $start_time = [Time::HiRes::gettimeofday()];

STDOUT->autoflush(1);

while (<>) {
  if (/ length (\d+):/) {
    $bytes_this_interval += $1;
    my $elapsed_seconds = Time::HiRes::tv_interval($start_time);
    if ($elapsed_seconds > $reporting_interval) {
       my $bps = $bytes_this_interval / $elapsed_seconds;
       printf "%02d:%02d:%02d %10.2f Bps\n", (localtime())[2,1,0],$bps;
       $start_time = [Time::HiRes::gettimeofday()];
       $bytes_this_interval = 0;
    }
  }
}

Это всего лишь пример, приспособиться к вкусу.

RedGrittyBrick
источник
Большое спасибо, я буду ждать вашего рабочего примера. Моя цель была такой же, как и в случае с $ bwm-ng -o plain -N -d, который показывает выходные данные как интерфейсы в битах, но завершается ошибкой, если используется интерфейс, кроме lo. С другой стороны, IPtraf показывает отличные байты в реальном времени. Но нет инструментов, которые могли бы сказать мне, как биты и байты в реальном времени в RX / TX для определенного интерфейса или любого интерфейса в целом и т. Д. Я
скучаю по
@YumYum: ответ обновлен.
RedGrittyBrick
1
@RedGrittyBrick Вы абсолютная легенда! Отличный сценарий! Большое спасибо за то, что поделились. Это отвечает на мой вопрос по адресу superuser.com/questions/395226/…
Eamorr
Этот должен работать в busybox bash на встроенных маршрутизаторах: gist.github.com/dagelf/8a842ed755354b31e79214042a4a4695
Dagelf
Это также достигается сvnstat -tr
St0rM
14

Использование как ниже из той же папки:

Чтобы проверить упаковщик для интерфейса: ./netpps.sh eth0

Чтобы проверить скорость на интерфейс: ./netspeed.sh eth0

Измерение пакетов в секунду на интерфейсе netpps.sh в качестве имени файла

#!/bin/bash

INTERVAL="1"  # update interval in seconds

if [ -z "$1" ]; then
        echo
        echo usage: $0 [network-interface]
        echo
        echo e.g. $0 eth0
        echo
        echo shows packets-per-second
        exit
fi

IF=$1

while true
do
        R1=`cat /sys/class/net/$1/statistics/rx_packets`
        T1=`cat /sys/class/net/$1/statistics/tx_packets`
        sleep $INTERVAL
        R2=`cat /sys/class/net/$1/statistics/rx_packets`
        T2=`cat /sys/class/net/$1/statistics/tx_packets`
        TXPPS=`expr $T2 - $T1`
        RXPPS=`expr $R2 - $R1`
        echo "TX $1: $TXPPS pkts/s RX $1: $RXPPS pkts/s"
done

Измерение пропускной способности сети на интерфейсе netspeed.sh в качестве имени файла

#!/bin/bash

INTERVAL="1"  # update interval in seconds

if [ -z "$1" ]; then
        echo
        echo usage: $0 [network-interface]
        echo
        echo e.g. $0 eth0
        echo
        exit
fi

IF=$1

while true
do
        R1=`cat /sys/class/net/$1/statistics/rx_bytes`
        T1=`cat /sys/class/net/$1/statistics/tx_bytes`
        sleep $INTERVAL
        R2=`cat /sys/class/net/$1/statistics/rx_bytes`
        T2=`cat /sys/class/net/$1/statistics/tx_bytes`
        TBPS=`expr $T2 - $T1`
        RBPS=`expr $R2 - $R1`
        TKBPS=`expr $TBPS / 1024`
        RKBPS=`expr $RBPS / 1024`
        echo "TX $1: $TKBPS kB/s RX $1: $RKBPS kB/s"
done

Пожалуйста, обратитесь на этот сайт для получения дополнительной информации http://xmodulo.com/measure-packets-per-second-throughput-high-speed-network-interface.html

Мутукумар Анбалаган
источник
Это нереальное решение для «конкретного порта или идентификатора процесса приложения», поскольку оно дает вам только скорость для интерфейса.
Мен
6

Самый простой в использовании и самый простой для контроля вывода и перенаправления в файл для непрерывной регистрации:

ifstat

Вероятно, поставляется с большинством дистрибутивов Linux, и может быть установлен с Brew на Mac

samthebest
источник
Спасибо за это. как остальные справляются с Mac? Попробую установить ifstat и посмотрю как пойдет. Некоторая дополнительная информация определенно была бы полезна.
nyxee
3

Я думаю, что вы можете использовать интерфейс proc для получения необходимой информации. Я создал этот небольшой сценарий оболочки под названием rt_traf.sh:

#!/bin/bash

cat /proc/$1/net/netstat | grep 'IpExt: ' | tail -n 1 | awk '{ print $8 "\t" $9 }'

Это напечатает входные и выходные октеты, разделенные табуляцией. Октеты, умноженные на 8, дадут вам бит / секунду, а затем, поделенные на 10 ^ 6, дадут вам мегабит / секунду. Конечно, вы можете добавить это в сценарий оболочки, чтобы отформатировать вывод, как вы хотите. Вы можете вызвать это с помощью PID вашего приложения, ./rt_traf.sh <PID>что даст вам мгновенное чтение вашего приложения с момента запуска. Для просмотра статистики в реальном времени в секунду вы можете обернуть скрипт оболочки в команду watch:

watch -n 1 ./rt_traf.sh <PID>

-nПараметр можно регулировать вплоть до десятых долей секунды. Чтобы сделать расчет во времени, я бы сделал что-то вроде этого:

PID=<PID>; START=`./rt_traf.sh $PID`;IN_START=`echo $START | awk '{ print $1 }'`; OUT_START=`echo $START | awk '{ print $2 }'`; sleep 10; END=`./rt_traf.sh $PID`; IN_END=`echo $END | awk '{ print $1 }'`; OUT_END=`echo $END | awk '{ print $2 }'`; IN_BPS=`echo "scale=2; (($IN_START-$IN_END)/10)/8" | bc`; OUT_BPS=`echo "scale=2; (($OUT_START-$OUT_END)/10)/8" | bc`; echo "In: " $IN_BPS "Bits/second"; echo "Out: " $OUT_BPS "Bits/second"

Опять же, математика может быть скорректирована на размер / время, которое вам нужно. Не самый элегантный или термоусадочный раствор, но он должен работать в крайнем случае.

d34dh0r53
источник
3
Это не правильно. / proc / <PID> / net / netstat не содержит данных для каждого процесса.
стащить
Чтобы расширить комментарий nab: /proc/<pid>/net/netstatвозвращает те же данные, что и proc/net/netstat, т.е. Вы получаете те же данные для любых / всех процессов.
EML
2

Мне просто нужно было измерить объем входящего и исходящего трафика mysql в старой системе, где perl не работал должным образом, поэтому я не мог удержаться от написания нескольких строк awk, которые служат той же цели измерения общего трафика, видимого tcpdump:

# tcpdump -l -e -n port 3306 | \
  awk '{
  t=substr($1, 0, 8);
  n=substr($9, 0, length($9)-1);
  if(t != pt){
    print t, sum;
    sum = 0;
  } else {
    sum += n
  }
  pt=t;
}'

tcpdump: WARNING: eth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
14:41:54 
14:41:55 466905
14:41:56 765220
14:41:57 741511
14:41:58 688219
14:41:59 492322
14:42:00 800087
14:42:01 1248608
14:42:02 1276476
14:42:03 755586
14:42:04 1029453
14:42:05 818298
^C32515 packets captured
32633 packets received by filter
107 packets dropped by kernel

И если вам больше нравятся однострочники, вот один для вас:

tcpdump -l -e -n port 3306 | awk '{t=substr($1,0,8);n=substr($9,0,length($9)-1);if(t!=pt){print t,sum;sum=0;}else{sum+=n}pt=t;}'
Ауримас Микалаускас
источник
elseЗаявление должно быть удалено в противном случае строки будут пропущены, и sumне будет точно. tcpdump -l -e -n port 3306 | awk '{t=substr($1,0,8);n=substr($9,0,length($9)-1);if(t!=pt){print t,sum;sum=0;};sum+=n;pt=t;}
Дэвид
0

Для каждого приложения можно сделать правило брандмауэра, используя xtables и модификацию ниже.

Это не отвечает на вопрос «на приложение», а только на вопрос «на интерфейс».

Ниже приведен скрипт, который работает на большинстве встроенных Linux-маршрутизаторов, таких как Ubiquiti и OpenWRT-совместимые, и получает его подробности из / proc / net / dev.

(И легко изменить на пакеты и т. Д.)

#!/bin/sh

SLP=1 # output / sleep interval
DEVICE=$1
IS_GOOD=0
for GOOD_DEVICE in `grep \: /proc/net/dev | awk -F: '{print $1}'`; do
    if [ "$DEVICE" = $GOOD_DEVICE ]; then
        IS_GOOD=1
        break
    fi
done

if [ $IS_GOOD -eq 0 ]; then
    echo "Device not found. Should be one of these:"
        grep ":" /proc/net/dev | awk -F: '{print $1}' | sed s@\ @@g 
    exit 1
fi

while true; do

LINE=`grep $1 /proc/net/dev | sed s/.*://`;
RECEIVED1=`echo $LINE | awk '{print $1}'`
TRANSMITTED1=`echo $LINE | awk '{print $9}'`
TOTAL=$(($RECEIVED1+$TRANSMITTED1))

sleep $SLP

LINE=`grep $1 /proc/net/dev | sed s/.*://`;
RECEIVED2=`echo $LINE | awk '{print $1}'`
TRANSMITTED2=`echo $LINE | awk '{print $9}'`
SPEED=$((($RECEIVED2+$TRANSMITTED2-$TOTAL)/$SLP))
INSPEED=$((($RECEIVED2-$RECEIVED1)/$SLP))
OUTSPEED=$((($TRANSMITTED2-$TRANSMITTED1)/$SLP))

printf "In: %12i KB/s | Out: %12i KB/s | Total: %12i KB/s\n" $(($INSPEED/1024)) $(($OUTSPEED/1024)) $((($INSPEED+$OUTSPEED)/1024)) ;

done;

Скопируйте вышеупомянутое в свой буфер обмена и затем в сеансе терминала на своем маршрутизаторе:

$ cat > /tmp/n.sh

затем: Ctrl + V (или правый клик / Вставить)

затем: Ctrl + D

$ chmod +x /tmp/n.sh

$ /tmp/n.sh eth0

Вы также можете вставить его в блокнот, а затем просто повторить вышеописанное, если вам нужно отредактировать его - не у всех встроенных маршрутизаторов есть редактор! Убедитесь, что вы скопировали все с # вверху до готового; внизу.

Приведенный выше пример с netpps великолепен, но не на всех устройствах есть смонтированная файловая система / sys. Возможно, вам также придется изменить / bin / bash на / bin / sh или наоборот.

Источник: https://gist.github.com/dagelf/ab2bad26ce96fa8d79b0834cd8cab549

Dagelf
источник
Пожалуйста, не размещайте один и тот же ответ на несколько вопросов. Если одна и та же информация действительно отвечает на оба вопроса, то один вопрос (обычно более новый) следует закрыть как дубликат другого. Вы можете указать это, проголосовав, чтобы закрыть его как дубликат, или, если у вас недостаточно репутации, поднять флаг, чтобы указать, что это дубликат. В противном случае настройте свой ответ на этот вопрос, а не просто вставляйте один и тот же ответ в нескольких местах.
DavidPostill
Вы разместили точно такой же комментарий на моем другом посте ... который был случайно настроен ... Такой ответ просто заставляет меня задуматься, почему я нашел время, чтобы внести свой вклад здесь.
Dagelf
Если он был настроен, то это происходило после того, как сообщения были автоматически помечены системой. У меня нет времени, чтобы прочитать каждое слово, чтобы увидеть, настроены они или нет.
DavidPostill
1
Единственная настройка, которую вы сделали, - добавить два предложения в начале вашего ансера. Остальное кажется идентичным. И эти два предложения не были в исходном ответе, как опубликовано - поэтому он был автоматически помечен как дублирующий ответ.
DavidPostill