วิธีรับสถิติเครือข่ายตามเวลาจริงใน Linux ด้วยรูปแบบ KB / MB / Bytes และสำหรับพอร์ตหรือแอปพลิเคชันเฉพาะกระบวนการ


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 ซึ่งแสดงผลลัพธ์เป็นบิตโดยส่วนต่อประสาน แต่ล้มเหลวหากใช้ส่วนต่อประสานยกเว้น lo ในทางกลับกัน IPtraf จะแสดงผลแบบเรียลไทม์ไบต์ที่ยอดเยี่ยม แต่ไม่มีเครื่องมือใดที่สามารถบอกฉันได้เหมือนบิตและไบต์เรียลไทม์ใน RX / TX สำหรับอินเทอร์เฟซที่ระบุหรืออินเทอร์เฟซใด ๆ รวมทั้งหมดฉันหายไป :-(
YumYumYum

@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

วัด Network Bandwidth บน Interface 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


นี่ไม่ใช่โซลูชันที่เป็นไปได้สำหรับ "พอร์ตเฉพาะหรือกระบวนการของแอปพลิเคชัน ID" เนื่องจากจะให้อัตราต่ออินเตอร์เฟสเท่านั้น
Mene

6

ใช้งานง่ายที่สุดและง่ายที่สุดในการควบคุมเอาต์พุตและเปลี่ยนเส้นทางไปยังไฟล์เพื่อการบันทึกอย่างต่อเนื่อง:

ifstat

อาจมาพร้อมกับการแจกแจงลินุกซ์ส่วนใหญ่และสามารถติดตั้งกับชงบน 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 }'

วิธีนี้จะพิมพ์ออคเต็นเข้า - ออกคั่นด้วยแท็บ Octets คูณ 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;}
david

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

คุณโพสต์ความคิดเห็นแบบเดียวกันในโพสต์อื่นของฉัน ... ซึ่งถูกปรับแต่งโดยบังเอิญ ... การตอบสนองแบบนี้ทำให้ฉันสงสัยว่าทำไมฉันถึงใช้เวลามีส่วนร่วมที่นี่
Dagelf

หากมีการปรับแต่งแล้วที่เกิดขึ้นหลังจากการโพสต์ถูกติดแท็กอัตโนมัติโดยระบบ ฉันไม่มีเวลาอ่านทุกคำเพื่อดูว่าพวกเขาได้รับการปรับแต่งหรือไม่
DavidPostill

1
การปรับแต่งเพียงอย่างเดียวที่คุณทำคือการเพิ่มสองประโยคที่จุดเริ่มต้นของ anser ของคุณ ส่วนที่เหลือดูเหมือนว่าเหมือนกัน และประโยคทั้งสองนั้นไม่ได้อยู่ในคำตอบดั้งเดิมที่โพสต์ซึ่งเป็นเหตุผลว่าทำไมจึงถูกตั้งค่าสถานะโดยอัตโนมัติว่าเป็นคำตอบที่ซ้ำกัน
DavidPostill
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.