Як отримати мережеву статистику в реальному часі в Linux у форматі KB / MB / Bytes та для конкретного порту або додатку processID?


22

Я IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Жоден з них не допомагає мені знаходити пакети в реальному часі, які надсилаються / отримуються з моєї програми у форматі KB або MB. Причина в тому, що я пишу заявку, де мені потрібно бути дуже впевненим, що стиснення правильне, але я не можу перевірити, щоб рухатися вперед.

Що я можу використовувати для відстеження дуже конкретної та точної статистики мережі в реальному часі?

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

Відповіді:


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;
    }
  }
}

Це лише приклад, підлаштовувати за смаком.


Велике спасибі, я буду чекати вашого робочого прикладу. Моя мета була такою, як я це робив з $ bwm-ng -o plain -N -d, який показує вихід як біт по інтерфейсам, але це failes, якщо використовується інтерфейс, крім lo. З іншого боку, IPtraf показує чудові байти в режимі реального часу. Але немає ніяких інструментів , які можуть сказати мені , як біти і байти в реальному часі в RX / TX для конкретного інтерфейсу або будь-якого інтерфейсу , як загальне і т.д. , мені НЕ вистачає його :-(
YumYumYum

@YumYum: відповідь оновлена.
RedGrittyBrick

1
@RedGrittyBrick Ви абсолютна легенда! Чудовий сценарій! Дуже дякую за обмін. Це відповідає на моє запитання на сторінці superuser.com/questions/395226/…
Eamorr

Цей повинен працювати в зайнятих
скрижалях

Цього також досягають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


Дякую за це. як інші справляються з 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"

Знову ж таки математику можна відрегулювати під потрібний розмір / раз. Не найелегантніше або стиснене обгортане рішення, але воно повинно працювати в дрібному вигляді.


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 - чудовий BTW - але не всі пристрої мають змонтовану файлову систему / sys. Можливо, вам також доведеться змінити / bin / bash на / bin / sh або навпаки.

Джерело: https://gist.github.com/dagelf/ab2bad26ce96fa8d79b0834cd8cab549


Будь ласка, не публікуйте однакову відповідь на кілька запитань. Якщо однакова інформація дійсно відповідає на обидва запитання, то одне питання (як правило, нове) має бути закрите як дублікат іншого. Ви можете вказати це, проголосувавши, щоб закрити його як дублікат або, якщо у вас недостатньо репутації для цього, підняти прапор, щоб вказати, що це дублікат. В іншому випадку підгадуйте свою відповідь на це питання і не просто вставляйте одну й ту ж відповідь у декілька місць.
DavidPostill

Ви написали такий самий коментар до мого іншого допису ... який був випадково налаштований ... Така відповідь просто змушує мене замислитися, чому я взяв час, щоб зробити свій внесок тут.
Дагельф

Якщо це було налаштовано, то це сталося після того, як система автоматично поставила підпис. Я не встигаю прочитати кожне слово, щоб побачити, чи вони налаштовані чи ні.
DavidPostill

1
Єдине налаштування, яке ви зробили, - це додати два речення на початку вашого ансеру. Решта здається ідентичною. І ці два речення не були в оригінальній відповіді, як опубліковані - саме тому воно було автоматично позначено як повторна відповідь.
DavidPostill
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.