Làm cách nào để có được thống kê mạng thời gian thực trong Linux với định dạng KB / MB / Byte và cho quy trình ứng dụng hoặc cổng cụ thể?


22

Tôi đã sử dụng IPTraf, Iftop, vnstat, bwm-ng, ifconfig -a. Không ai trong số họ giúp tôi tìm các gói thời gian thực đang được gửi / nhận từ ứng dụng của tôi ở định dạng KB hoặc MB. Lý do là tôi đang viết một ứng dụng, nơi tôi cần chắc chắn rằng việc nén của mình là chính xác, nhưng tôi không thể kiểm tra để tiến lên.

Những gì tôi có thể sử dụng để theo dõi số liệu thống kê mạng thời gian thực rất cụ thể và chính xác?

nhập mô tả hình ảnh ở đây

Câu trả lời:


27

Ứng dụng của bạn có thể đang gửi các gói đến một số cổng UDP hoặc TCP cụ thể hoặc đến một địa chỉ IP cụ thể.

Do đó, bạn có thể sử dụng một cái gì đó như TCPdump để nắm bắt lưu lượng đó.

TCPdump không cung cấp cho bạn các số liệu thống kê theo thời gian thực mà bạn mong muốn nhưng bạn có thể cung cấp kết quả đầu ra cho thứ gì đó (tôi sẽ cố gắng cập nhật câu trả lời này bằng câu trả lời sau).


Cập nhật:

$ 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

Tôi đã ngắt nó sau một phút bằng cách nhấn Ctrl + C.

Bạn cần thêm một biểu thức lọc phù hợp ở cuối tcpdumplệnh để chỉ bao gồm lưu lượng truy cập được tạo bởi ứng dụng của bạn (ví dụ port 123)

Chương trình netbpsnày là:

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

Đó chỉ là một ví dụ, điều chỉnh theo sở thích.


Rất cám ơn, tôi sẽ chờ ví dụ làm việc của bạn. Mục tiêu của tôi giống như tôi đã làm với $ bwm-ng -o plain -N -d, hiển thị đầu ra dưới dạng bit theo giao diện nhưng không thành công nếu giao diện được sử dụng ngoại trừ lo. Mặt khác, IPtraf hiển thị byte thời gian thực tuyệt vời. Nhưng không có công cụ nào có thể cho tôi biết như bit và byte thời gian thực trong RX / TX cho giao diện cụ thể hoặc bất kỳ giao diện nào, v.v. Tôi đang thiếu nó :-(
YumYumYum

@YumYum: trả lời cập nhật.
RedGrittyBrick

1
@RedGrittyBrick Bạn là huyền thoại tuyệt đối! Kịch bản tuyệt vời! Cảm ơn rât nhiêu vê nhưng chia sẻ. Câu trả lời này cho câu hỏi của tôi tại superuser.com/questions/395226/
Ấn

Cái này sẽ hoạt động trong bashbox
Dagelf

Điều này cũng đạt được với vnstat -tr
St0rM

14

Cách sử dụng như dưới đây từ cùng một thư mục:

Để kiểm tra trình đóng gói trên mỗi giao diện: ./netpps.sh eth0

Để kiểm tra tốc độ trên mỗi giao diện: ./netspeed.sh eth0

Đo gói mỗi giây trên một giao diện netpps.sh làm tên tệp

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

Đo băng thông mạng trên một giao diện Netspeed.sh làm tên tệp

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

Vui lòng tham khảo trang web này để biết thêm http://xmodulo.com/measure-packets-per-second-ENCput-high-speed-network-interface.html


Đây không phải là một giải pháp khả thi cho "cổng cụ thể hoặc quy trình ứng dụng" vì nó chỉ cung cấp cho bạn tỷ lệ trên mỗi giao diện.
Mene

6

Dễ sử dụng nhất và dễ kiểm soát đầu ra nhất và chuyển hướng đến tệp để ghi nhật ký liên tục:

ifstat

Có lẽ đi kèm với hầu hết các bản phân phối linux và có thể được cài đặt với brew trên mac


cảm ơn vì điều đó. Làm thế nào để những người khác công bằng với Mac? Tôi sẽ thử cài đặt ifstat và xem nó hoạt động như thế nào. Một số thông tin chắc chắn sẽ có ích.
nyxee

3

Tôi nghĩ bạn có thể sử dụng giao diện Proc để lấy thông tin bạn cần. Tôi đã tạo tập lệnh shell nhỏ này được gọi là rt_traf.sh:

#!/bin/bash

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

Điều này sẽ in các octet vào và ra được phân tách bằng một tab. Octets nhân với 8 sẽ cung cấp cho bạn bit / giây và sau đó chia cho 10 ^ 6 sẽ cung cấp cho bạn megabits / giây. Tất nhiên bạn có thể thêm phần này vào shell script để định dạng đầu ra theo cách bạn muốn. Bạn có thể gọi điều này với PID của ứng dụng của bạn như vậy./rt_traf.sh <PID> sẽ cho bạn đọc ngay lập tức ứng dụng của bạn kể từ khi khởi động. Để xem số liệu thống kê thời gian thực mỗi giây, bạn có thể gói tập lệnh shell trong lệnh xem:

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

Các -nthông số có thể điều chỉnh tất cả các con đường xuống phần mười của một giây. Để làm một phép tính theo thời gian tôi sẽ làm một cái gì đó như thế này:

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"

Một lần nữa toán học có thể được điều chỉnh cho kích thước / lần bạn cần. Không phải là giải pháp bọc thanh lịch hoặc thu nhỏ nhất nhưng nó nên hoạt động trong một nhúm.


3
Cái này sai. / Proc / <PID> / net / netstat không chứa dữ liệu trên mỗi quy trình.
nab

Để mở rộng nhận xét của nab: /proc/<pid>/net/netstattrả về cùng một dữ liệu như proc/net/netstat, nghĩa là. bạn nhận được cùng một dữ liệu cho bất kỳ / tất cả các quy trình.
EML

2

Tôi chỉ cần đo lượng lưu lượng truy cập mysql vào và ra trên một hệ thống cũ mà perl không hoạt động chính xác, vì vậy tôi không thể cưỡng lại việc viết một vài dòng awk phục vụ cho cùng một mục tiêu là đo tổng lưu lượng truy cập mà tcpdump nhìn thấy:

# 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

Và nếu bạn thích một lớp lót tốt hơn, thì đây là một cái cho bạn:

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

Câu elselệnh nên được loại bỏ nếu không các dòng sẽ bị bỏ qua và sumsẽ không chính xác. 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

Mỗi ứng dụng có thể được thực hiện với quy tắc tường lửa bằng xtables và sửa đổi bên dưới.

Điều này không trả lời câu hỏi "mỗi ứng dụng" mà chỉ trả lời câu hỏi "trên mỗi giao diện".

Dưới đây là một tập lệnh hoạt động trên hầu hết các bộ định tuyến Linux nhúng như các bộ tương thích Ubiquiti và OpenWRT và nhận thông tin chi tiết từ / Proc / net / dev.

(Và dễ dàng thay đổi thành các gói, v.v.)

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

Sao chép phần trên vào bảng tạm của bạn và sau đó trong phiên cuối trên bộ định tuyến của bạn:

$ cat > /tmp/n.sh

sau đó: Ctrl + V (hoặc nhấp chuột phải / Dán)

sau đó: Ctrl + D

$ chmod +x /tmp/n.sh

$ /tmp/n.sh eth0

Bạn cũng có thể dán nó vào một notepad, sau đó chỉ cần lặp lại ở trên nếu bạn cần chỉnh sửa nó - không phải tất cả các bộ định tuyến nhúng đều có trình chỉnh sửa! Hãy chắc chắn rằng bạn sao chép mọi thứ từ # ở trên cùng để hoàn thành; ở phía dưới

Ví dụ netpps ở trên là BTW tuyệt vời - nhưng không phải tất cả các thiết bị đều có hệ thống tập tin được gắn / sys. Bạn cũng có thể phải thay đổi / bin / bash thành / bin / sh hoặc ngược lại.

Nguồn: https://gist.github.com/dagelf/ab2bad26ce96fa8d79b0834cd8cab549


Xin vui lòng không gửi cùng một câu trả lời cho nhiều câu hỏi. Nếu cùng một thông tin thực sự trả lời cả hai câu hỏi, thì một câu hỏi (thường là câu hỏi mới hơn) nên được đóng lại như một bản sao của câu hỏi khác. Bạn có thể chỉ ra điều này bằng cách bỏ phiếu để đóng nó dưới dạng trùng lặp hoặc, nếu bạn không đủ danh tiếng cho điều đó, hãy giơ cờ để cho biết đó là bản sao. Mặt khác, điều chỉnh câu trả lời của bạn cho câu hỏi này và không chỉ dán cùng một câu trả lời ở nhiều nơi.
DavidPostill

Bạn đã đăng chính xác cùng một bình luận trên bài đăng khác của tôi ... được tùy chỉnh một cách tình cờ ... Loại phản hồi này chỉ khiến tôi tự hỏi tại sao tôi lại dành thời gian để đóng góp ở đây.
Dagelf

Nếu nó được tùy chỉnh thì điều đó đã xảy ra sau khi bài viết được hệ thống tự động điền. Tôi không có thời gian để đọc từng từ để xem chúng có được tùy chỉnh hay không.
DavidPostill

1
Tùy chỉnh duy nhất bạn đã làm là thêm hai câu khi bắt đầu anser của bạn. Phần còn lại có vẻ giống hệt nhau. Và hai câu đó không có trong câu trả lời ban đầu như đã đăng - đó là lý do tại sao nó được tự động gắn cờ là một câu trả lời trùng lặp.
DavidPostill
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.