Estatísticas de tráfego de rede

Publicado por Khayla (Alexandre) Elias dos Santos (última atualização em 20/08/2015)

[ Hits: 7.479 ]

Download net-monitor

Download 1439318928.net-monitor (versão 2)




Exibe as estatísticas do tráfego de rede de uma determinada interface na tela do terminal.

Os dados utilizados são referentes a quantidade de bytes enviados (rx) e recebidos (tx). São exibidos os valores da velocidade atual, do último minuto, dos últimos cinco minutos e dos últimos quinze minutos. Além disso, o máximo dos últimos quinze minutos também é calculado e exibido.

Modo de usar: vide comentários incluídos no topo do código.

  



Versões atualizadas deste script

Versão 2 - Enviado por Khayla (Alexandre) Elias dos Santos em 11/08/2015

Changelog: Versão 2015-08-11 do Monitor de Tráfego de Rede para terminal em modo texto.

Principais alterações:

- Autorreajuste do "delay" considerando o tempo de execução;
- Maior aproximação dos valores do tráfego de dados;
- Melhoria na estrutura e clareza do código.

Download 1439318928.net-monitor


Esconder código-fonte

#!/bin/bash

# DESCRIÇÃO:
#
#   Monitor de rede para terminal. Exibe as estatísticas do tráfego de rede de uma
# determinada interface. Os dados utilizados são referentes a quantidade de bytes
# enviados(rx) e recebidos(tx). Sã exibidas os valores da velocidade atual, do último
# minuto, dos últimos cinco minutos e dos últimos quinze minutos. Além disso, são
# exibidos também os máximos dos últimos quinze minutos.
#
# Parâmetro de entrada: interface de rede (eth0, wlan0, ppp0, ...)
#
# Nota: largura mínima do terminal recomendada para boa visualização: 80 colunas
#
# MODO DE USO:
#
#   net-monitor [ interface ]
#
# Exemplo de uso:
#
#   net-monitor eth0
#
# DESENVOLVIDO POR: Alexandre Elias dos Santos ([email protected])
# DATA:         Fevereiro de 2015.

dev=$1; dev=${dev:=ppp0} # interface de rede
units=128   # unidades: 1 byte = 1 Kbit/128 = 1 KB/1024
label="Kb/s"    # rótulo para unidade

clear; tput civis   # oculta o cursor
printf "Netmonitor - Monitor de Rede\n"
printf "Por Alexandre Elias dos Santos ([email protected])"
sleep 3

tx1=0; rx1=0; cont1=0; cont5=0; cont15=0
TX=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
RX=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
TX5=(0 0 0 0 0); RX5=( 0 0 0 0 0)
TX15=(0 0 0 0 0); RX15=( 0 0 0 0 0)
MTXtx=(0 0 0 0 0); MTXrx=( 0 0 0 0 0)
#charUp="\U25B2"; charDown="\U25BC"

function restaura(){
    tput clear
    cols0=$(tput cols)

    printf "Largura do terminal: $cols0\nDispositivo: $dev"
    sleep 2
    [ $cols0 -lt 80 ] && (printf "\n\033[31mNúmero de colunas insuficiente!\e[m"; sleep 2; clear)

    tput cup 0 0; printf '\e[1;7m%-7s\e[m' "iface"
    tput cup 1 0; printf '\e[1;7m%-7s\e[m' "[$dev]"

    tput cup 0 7; printf "\e[1;7;44;34m%$((`tput cols`-7))s" "$label"
    tput cup 0 63; printf "≤\e[m"

    tput cup 1 7; printf "\e[1;7;45;35m%$((`tput cols`-7))s" "$label"
    tput cup 1 63; printf "≤\e[m"

    tput cup 0 13; printf '\e[1;30;44m%-3s\e[m' "   "
    tput cup 1 13; printf '\e[1;30;45m%-3s\e[m' "   "

    tput cup 0 8; printf '\e[1;44m%-2s\e[m' " TX "
    tput cup 1 8; printf '\e[1;45m%-2s\e[m' " RX "

    tput cup 0 17; printf '%-9s' " Average"
    tput cup 1 17; printf '%-9s' " now"
    tput cup 0 29; printf '%-9s' " Last"
    tput cup 1 29; printf '%-9s' " minute"
    tput cup 0 41; printf '%-9s' " Last 5"
    tput cup 1 41; printf '%-9s' " minutes"
    tput cup 0 53; printf '%-9s' " Last 15"
    tput cup 1 53; printf '%-9s' " minutes"
    tput cup 0 65; printf '\e[31m%-9s' " Max"
    tput cup 1 65; printf '%-9s\e[m' " last 15"
    ip route| grep -q $dev || waiting
    rx="`ip -s link show dev $dev|head -4|tail -1|sed 's/  */;/g'|cut -d";" -f2`" # bytes recebidos
    tx="`ip -s link show dev $dev|tail -1|sed 's/  */;/g'|cut -d";" -f2`" # bytes enviados
} # restaura - restaura layout


function waiting(){
    local flag=0
    tput clear
    printf "Searching network interface $dev..."

    while [ "$flag" = "0" ]; do
        sleep 3
        (ip route|grep -q $dev) && flag="1"
    done # seleciona interface
} # waiting - aguarda por um interface conectada

function reinicia(){
    ip route|grep $dev || waiting
    restaura
} # - reinicia

reinicia; sleep 1


while true
do
    rx1="`ip -s link show dev $dev|head -4|tail -1|sed 's/  */;/g'|cut -d";" -f2`"  # recebidos
    tx1="`ip -s link show dev $dev|tail -1|sed 's/  */;/g'|cut -d";" -f2`"      # enviados
    let deltatx=$tx1-${tx:=0}; let deltarx=$rx1-${rx:=0}

    # ============= N E T W O R K   L E D =================================
    if [ "${deltatx:=0}" -eq 0 ]; then
        test `tput cols` -ne $cols0 && restaura
        tput cup 0 14; printf '\e[1;30;44m%-1s\e[m' "▲"
    else
        tput cup 0 14; printf '\e[1;31;44m%-1s\e[m' "▲"
    fi # LED TX

    if [ "${deltarx:=0}" -eq 0 ]; then
        ip route| grep -q $dev || reinicia # verifica dispositivo conectado
        tput cup 1 14; printf '\e[1;30;45m%-1s\e[m' "▼"
    else
        tput cup 1 14; printf '\e[1;32;45m%-1s\e[m' "▼"
    fi # LED RX

    #=== C O N V E R Ç Ã O   D E   U N I D A D E S =======================
    deltatx=`echo "scale=2; $deltatx/$units"|bc`    # tx/s
    deltarx=`echo "scale=2; $deltarx/$units"|bc`    # rx/s

    # ==================== E S T A T I S T I C A S =======================
    tput cup 0 17
    if [ "${#deltatx}" -gt 9 ];then
        printf '%9.f' "${deltatx/./,}"
    else    printf '%9.1f' "${deltatx/./,}"
    fi  # MEDIA ATUAL TX

    tput cup 1 17
    if [ "${#deltarx}" -gt 9 ];then
    printf '%9.f' "${deltarx/./,}"
    else    printf '%9.1f' "${deltarx/./,}"
    fi  #MEDIA ATUAL RX


    # ATUALIZA MAXIMOS DE TX e RX
    [ "`echo "scale=0; $deltatx*100/1"|bc`" -gt "`echo "scale=0; ${MTXtx[4]}*100/1"|bc`" ] && MTXtx[4]=$deltatx
    [ "`echo "scale=0; $deltarx*100/1"|bc`" -gt "`echo "scale=0; ${MTXrx[4]}*100/1"|bc`" ] && MTXrx[4]=$deltarx

    if [ "$cont1" -eq 4 ]; then
        # MÉDIA DO ÚLTIMO MINUTO
        soma_tx=0; soma_rx=0
        for i in `seq 0 13`
        do
            TX[$i]=${TX[$(($i+1))]}
            RX[$i]=${RX[$(($i+1))]}
            soma_tx="`echo "scale=2; $soma_tx+${TX[$i]}"|bc`"
            soma_rx="`echo "scale=2; $soma_rx+${RX[$i]}"|bc`"
        done

        TX[14]=$deltatx
        RX[14]=$deltarx

        soma_tx="`echo "scale=2; $soma_tx+$deltatx"|bc`"
        soma_rx="`echo "scale=2; $soma_rx+$deltarx"|bc`"

        mi_t="`echo "scale=2; $soma_tx/15"|bc`"
        mi_r="`echo "scale=2; $soma_rx/15"|bc`"

        tput cup 0 29
        if [ "${#mi_t}" -gt 9 ]; then
            printf '%9.f' "${mi_t/./,}"
        else    printf '%9.1f' "${mi_t/./,}"
        fi  # ÚLTIMO MINUTO RX

        tput cup 1 29 # printf '%9.1f' "${mi_r/./,}" # ÚLTIMO MINUTO
                if [ "${#mi_r}" -gt 9 ]; then
                        printf '%9.f' "${mi_r/./,}"
                else    printf '%9.1f' "${mi_r/./,}"
                fi      # ÚLTIMO MINUTO TX

        cont1=0; let cont5=$cont5+4

        if [ "$cont5" -eq 60 ]; then
            # MÉDIA DOS ÚLTIMOS 5 MINUTOS
            mi_t5=0; mi_r5=0
            for i in `seq 0 3`
            do
                TX5[$i]=${TX5[$(($i+1))]}
                RX5[$i]=${RX5[$(($i+1))]}
                mi_t5="`echo "scale=2; print ($mi_t5 + ${TX5[$i]})"|bc`"
                mi_r5="`echo "scale=2; print ($mi_r5 + ${RX5[$i]})"|bc`"
            done # somatorio de mi_t5
            TX5[4]=$mi_t; RX5[4]=$mi_r

            mi_t5="`echo "scale=2; ($mi_t5 + $mi_t)/5"|bc`" # 640 = 128 * 5
            mi_r5="`echo "scale=2; ($mi_r5 + $mi_r)/5"|bc`"

            tput cup 0 41
            if [ "${#mi_t5}" -gt 9 ];then
                printf '%9.f' "${mi_t5/./,}"
            else    printf '%9.1f' "${mi_t5/./,}"
            fi  # ÚLTIMOS CINCO MINUTOS TX

            tput cup 1 41
            if [ "${#mi_r5}" -gt 9 ];then
                printf '%9.f' "${mi_r5/./,}"
            else    printf '%9.1f' "${mi_r5/./,}"
            fi      # ÚLTIMOS CINCO MINUTOS RX
            cont5=0; let cont15=$cont15+60

            if [ "$cont15" -eq 180 ]; then
                # MÉDIA DOS ÚLTIMOS 15 MINUTOS
                mi_t15=0; mi_r15=0;maior_tx=0.00; maior_rx=0.00
                for i in `seq 0 3`
                do
                    TX15[$i]=${TX15[$(($i+1))]}
                    RX15[$i]=${RX15[$(($i+1))]}
                    mi_t15="`echo "scale=2; print ($mi_t15 + ${TX15[$i]})"|bc`"
                    mi_r15="`echo "scale=2; print ($mi_r15 + ${RX15[$i]})"|bc`"

                    [ "`echo "scale=0; ${MTXtx[$i]}*100/1"|bc`" -gt "`echo "scale=0; $maior_tx*100/1"|bc`" ] && maior_tx=${MTXtx[$i]}
                    [ "`echo "scale=0; ${MTXrx[$i]}*100/1"|bc`" -gt "`echo "scale=0; $maior_rx*100/1"|bc`" ] && maior_rx=${MTXrx[$i]}
                    MTXtx[$i]=${MTXtx[$(($i+1))]}
                    MTXrx[$i]=${MTXrx[$(($i+1))]}
                done # somatorio de mi_t15
                TX15[4]=$mi_t5; RX15[4]=$mi_r5

                [ "`echo "scale=0; ${MTXtx[4]}*100/1"|bc`" -gt "`echo "scale=0; $maior_tx*100/1"|bc`" ] && maior_tx=${MTXtx[4]}
                [ "`echo "scale=0; ${MTXrx[4]}*100/1"|bc`" -gt "`echo "scale=0; $maior_rx*100/1"|bc`" ] && maior_rx=${MTXrx[4]}
                MTXtx[4]=0; MTXrx[4]=0

                mi_t15="`echo "scale=2; ($mi_t15 + $mi_t5)/5"|bc`" # 640 = 128 * 5
                mi_r15="`echo "scale=2; ($mi_r15 + $mi_r5)/5"|bc`"

                tput cup 0 53
                if [ "${#mi_t15}" -gt 9 ]; then
                    printf '%9.f' "${mi_t15/./,}"
                else    printf '%9.1f' "${mi_t15/./,}"
                fi  # ULTIMOS 15 TX

                tput cup 1 53
                if [ "${#mi_r15}" -gt 9 ]; then
                    printf '%9.f' "${mi_r15/./,}"
                else    printf '%9.1f' "${mi_r15/./,}"
                fi  # ULTIMOS 15 RX

                tput cup 0 65
                if [ "${#maior_tx}" -gt 9 ]; then
                    printf '\e[31m%9.f' "${maior_tx/./,}"
                else    printf '\e[31m%9.1f' "${maior_tx/./,}"
                fi  # MAXIMO EM 15 MIN. TX

                tput cup 1 65
                if [ "${#maior_rx}" -gt 9 ]; then
                    printf '\e[31m%9.f' "${maior_rx/./,}"
                else    printf '\e[31m%9.1f' "${maior_rx/./,}"
                fi  # MAXIMO EM 15 MIN. RX

                cont15=0
            fi # Média dos últimos 15 minutos
        fi # Média dos últimos 5 minutos
    fi #  Média do último minuto

    tx=$tx1; rx=$rx1; let cont1++
    sleep .95 # intervalo de 1 segundo com desconto de 5% para processamento. Pode ser reajustado.
done # loop

Scripts recomendados

Trocando MAC address de placa de rede

Script para fazer download no rapidshare com conta premium

Compilação automática do GCC-4.7.3 para Ubuntu 12.04+ 64 bits

Update browscap

S-phoenix desliga/reinicia, quantos estão logado no PC, tempo ligado


  

Comentários
[1] Comentário enviado por Lwkas em 07/08/2015 - 09:26h

Muito Bom, parabéns.

[2] Comentário enviado por wagnerfs em 10/08/2015 - 11:11h

Legal! Obrigado por compartilhar o conhecimento.
_________________________
Wagner F. de Souza
Técnico/Instrutor de Informática
"GNU/Linux for human beings."
LPI ID: LPI000297782

[3] Comentário enviado por zumodevidrio em 11/08/2015 - 10:51h

Funciona ótimo. Parabéns pelo script.

Será que tem algum jeito de armazenar as informações do script num Logfile?

[4] Comentário enviado por aleniac em 11/08/2015 - 15:39h

Obrigado a todos que gostaram! Já estou publicando uma versão atualizada. Contudo, ainda parece haver um problema encontrado em tempo de execução: o consumo de memória e o tempo de processamento parecem não serem limitados, isto é, vão aumentando lentamente enquanto o script estiver em execução. Mas após o terceiro minuto, nenhuma variável é criada e a execução segue a mesma rotina. Quem puder fazer algum comentário a respeito, eu agradeço. ;)

Alexandre Elias dos Santos

[5] Comentário enviado por JJota em 13/08/2015 - 10:36h

No meu CentOS estava gerando erro do BC... ele não estava instalado... funcionou apos a instalação porém agora gera erro no printf:

./net-monitor.sh: line 128: printf: 6,62: invalid numberralid number

o printf esta instalado no path /usr/bin/printf

sabe me dizer o que pode ser?

Abraços

[6] Comentário enviado por aleniac em 13/08/2015 - 15:45h


[5] Comentário enviado por JJota em 13/08/2015 - 10:36h

No meu CentOS estava gerando erro do BC... ele não estava instalado... funcionou apos a instalação porém agora gera erro no printf:

./net-monitor.sh: line 128: printf: 6,62: invalid numberralid number

o printf esta instalado no path /usr/bin/printf

sabe me dizer o que pode ser?

Abraços



Não testei este script em outras distribuições diferente do Xubuntu, JJota. Se isto ocorre na imprensão de todas varíaveis com casas decimais, parece ser pela substituição dos separadores dos decimais, ou seja, o ponto (.) é substituído pela vírgula (,) no momento da impressão. Contudo, o bc gera saída com ponto. No Ubuntu ocorre erro se não for feita a substituição semelhante abaixo:

printf '%9.f' "${mi_r/./,}"

Faça um teste eliminando as subtituições nas saídas, conforme abaixo:

printf '%9.f' "${mi_r}"

ou ainda

printf '%9.f' "$mi_r"

Se realmente for isso, pode então ser feita uma substituição em todas ocorrências do código nas linhas com "printf" semelhantes.

Abraços.

[7] Comentário enviado por removido em 15/08/2015 - 00:46h


Favoritado!!!
A liberdade indocil e domada pela propria desgraça -William Shakespeare

[8] Comentário enviado por sergeimartao em 03/09/2015 - 14:05h

Funcionou muito bem no Manjaro, precise apenas comentar as linhas

#echo "$dev"|grep -qE "eth[0-9]|ppp[0-9]|wlan[0-9]|usb[0-9]"
#if [ "$?" != 0 ]; then
# printf "`basename $0`:$LINENO: no such device $dev \naborting\n" >&2
# exit 19
#fi # check device name

Pois a interface de rede é enp6s0, imagino que outras distribuições baseadas em Arch vão precisar fazer isso.
Parabens!

[9] Comentário enviado por aleniac em 11/09/2015 - 22:15h

Outra opção, seria acrescentar a sua interface de rede na primeira linha ignorada, sergeimartao. Veja no final da linha abaixo:

echo "$dev"|grep -qE "eth[0-9]|ppp[0-9]|wlan[0-9]|usb[0-9]|enp6s0"


Abraços

Alexandre Elias dos Santos


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts