Como obter estatísticas de rede em tempo real no Linux com o formato KB / MB / Bytes e para a porta específica ou o processID do aplicativo?

19

Eu usei IPTraf , Iftop , vnstat , bwm-ng , ifconfig -a . Nenhum deles está me ajudando a encontrar pacotes em tempo real que estão sendo enviados / recebidos do meu aplicativo no formato KB ou MB. O motivo é que estou escrevendo um aplicativo, no qual preciso ter certeza de que a compactação está correta, mas não posso testar para avançar.

O que eu posso usar para rastrear estatísticas de rede em tempo real muito precisas e específicas?

    
por YumYumYum 13.11.2011 / 10:10

6 respostas

21

Seu aplicativo provavelmente está enviando pacotes para um número de porta UDP ou TCP específico ou para um endereço IP específico.

Você pode, portanto, usar algo como o TCPdump para capturar esse tráfego.

O TCPdump não fornece as estatísticas em tempo real que você deseja, mas você pode alimentar sua saída para algo que faz (tentarei atualizar essa resposta com uma resposta posterior).

Atualização:

$ 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

Eu interrompi isso depois de um minuto pressionando Ctrl + C.

Você precisaria adicionar uma expressão de filtro adequada ao final do comando tcpdump para incluir apenas o tráfego gerado por seu aplicativo (por exemplo, port 123 )

O programa netbps é este:

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

É apenas um exemplo, ajuste a gosto.

    
por 13.11.2011 / 12:01
10

Uso abaixo da mesma pasta:

Para verificar o empacotador por interface: ./netpps.sh eth0

Para verificar a velocidade por interface: ./netspeed.sh eth0

Medir pacotes por segundo em uma interface netpps.sh como nome de arquivo

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

Medir a largura de banda da rede em uma interface netspeed.sh como nome de arquivo

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

Por favor, consulte este site para mais informações link

    
por 08.11.2014 / 18:14
3

Mais fácil de usar e mais fácil de controlar a saída e redirecionar para o arquivo para registro contínuo:

ifstat

Provavelmente vem com a maioria das distribuições do Linux, e pode ser instalado com brew no mac

    
por 30.10.2013 / 11:19
3

Acho que você pode usar a interface proc para obter as informações necessárias. Eu criei este pequeno script de shell chamado rt_traf.sh:

#!/bin/bash

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

Isso imprimirá os octetos de entrada e saída separados por uma guia. Os octetos multiplicados por 8 lhe darão bits / segundo e depois divididos por 10 ^ 6 darão megabits / segundo. Claro que você pode adicionar isso ao script de shell para formatar a saída como você deseja. Você pode chamar isso com o PID do seu aplicativo, como ./rt_traf.sh <PID> , que lhe dará uma leitura instantânea do seu aplicativo desde a inicialização. Para ver as estatísticas em tempo real por segundo, você pode incluir o script de shell no comando watch:

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

O parâmetro -n pode ser ajustado até os décimos de segundo. Para fazer um cálculo ao longo do tempo eu faria algo assim:

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"

Novamente, a matemática pode ser ajustada para o tamanho / hora que você precisa. Não é a solução mais elegante ou encolhida, mas deve funcionar bem.

    
por 13.11.2011 / 12:35
2

Eu só precisava medir quanto tráfego do mysql entra e sai de um sistema antigo onde o perl não funcionava corretamente, então não pude resistir a escrever algumas linhas de awk que servem ao mesmo objetivo de medir o tráfego total visto por 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

E se você gosta mais de uma linha, aqui está uma para você:

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;}'
    
por 03.03.2016 / 21:48
0

Por aplicativo pode ser feito com uma regra de firewall usando xtables e uma modificação do abaixo.

Isso não responde à pergunta "por aplicativo", mas apenas à pergunta "por interface".

Abaixo está um script que funciona na maioria dos roteadores Linux embarcados, como os compatíveis com Ubiquiti e OpenWRT, e obtém seus detalhes em / proc / net / dev.

(e fácil de mudar para pacotes, etc.)

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

Copie o texto acima para a área de transferência e, em seguida, em uma sessão de terminal no seu roteador:

$ cat > /tmp/n.sh

depois: Ctrl + V (ou clique direito / Colar)

depois: Ctrl + D

$ chmod +x /tmp/n.sh

$ /tmp/n.sh eth0

Você também pode colá-lo em um bloco de notas e depois repetir o que precede, se precisar editá-lo - nem todos os roteadores incorporados têm um editor! Certifique-se de copiar tudo, desde o # no topo até o final; na parte inferior.

O exemplo do netpps acima é ótimo BT - mas nem todos os dispositivos têm um sistema de arquivos montado / sys. Você também pode ter que mudar o / bin / bash para / bin / sh ou vice-versa.

Fonte: link

    
por 23.05.2018 / 18:44