lsof: meça a taxa de E / S de um soquete fd

2

Estou escrevendo um script que analisa a saída de lsof para mostrar uma lista de quais processos têm sockets abertos (semelhante ao que netstat mostra). lsof também me fornece um descritor de arquivo. O que quero fazer agora é que meu script também informe quantos dados (em KB / s) estão sendo enviados / recebidos por meio desse soquete.

Até agora, olhei para:

  1. nethogs : indica a E / S da rede de um processo, mas apenas por processo, não por soquete.
  2. iotop : indica a E / S do disco por processo; não parece ser capaz de informar a E / S da rede nem a E / S por soquete.
  3. /proc/pid/fd/ : Não parece que isso pode me dizer muita coisa.
  4. fatrace : me diz quais arquivos (não soquetes) um processo acessa.
  5. iostat : indica estatísticas médias de E / S por disco.
  6. tcpdump : me dá um dump de todo o tráfego por IP; não parece ser capaz de dizer a qual soquete o tráfego pertence.
  7. strace -p pid -e trace=network -s 0 : me diz toda vez que o processo dado chama certas funções de socket, o que parece ser útil, mas na prática está me dando muito recvfrom(13, 0x7feed8fb3074, 4096, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
  8. strace -p pid -e trace=read,write -s : diz-me o resultado de cada read / write chamada.

strace parece promissor, mas não tenho certeza se estou trabalhando corretamente (é read,write o suficiente?), além disso, parece que haveria muita sobrecarga. (Para cada processo com um socket aberto eu teria que executar uma instância de strace e analisar a saída.)

O kernel do Linux fornece um meio mais agradável de medir quanto de E / S está acontecendo por fd / socket? Possivelmente algo poderia ser configurado com iptables ou hackeando nethogs ?

    
por Rena 06.02.2015 / 00:54

1 resposta

1

Considere o uso de SystemTap . É um clone do DTrace, mas para Linux - ele compila o módulo do kernel que corrige dinamicamente o kernel e tem acesso total aos seus dados (portanto, lsof pode não ser necessário nesse caso).

No entanto, quanto mais informações você perguntar, mais complicado e script específico da versão do kernel se tornará.

Por exemplo, um utilitário semelhante a estatísticas para sockets será parecido com:

global stats;

probe begin {
    printf("%14s %6s %12s %5s %5s %8s\n", "NAME", "PID", "EXECNAME",
                "INO", "OPS/S", "BYTES");
}

function file_ino:long (file:long)
{
    if(file == 0) return -1;
    d_inode = @cast(file, "file", "kernel")->f_inode;
    if (d_inode == 0) return -1;
    return @cast(d_inode, "inode", "kernel")->i_ino;
}

probe socket.send, socket.receive {
    if(success == 0) next;

    /* Get inode number for a socket. Depending on 
       operation, struct file is contained in different fields. 
       Determine that field and get inode number */
    ino = -1;
    if(@defined($sock)) {
        ino = file_ino($sock->file);
    }
    else if(@defined($iocb)) {
        ino = file_ino($iocb->ki_filp);
    }

    stats[pid(), execname(), ino, name] <<< size;
}

probe timer.s(1) {
    /* Every 1 second print statistics */
    foreach([pid+, ename, ino, name] in stats) {
        printf("%14s %6d %12s %5d %5d %8d\n", name, pid, ename, ino, 
                    @count(stats[pid, ename, ino, name]), 
                    @sum(stats[pid, ename, ino, name]));
    }
    delete stats;
}

Eu testei no vanilla Linux 3.12, mas como você pode ver a lógica de obter um número de inode depende da estrutura interna do kernel.

Como você pode ver, na maioria das vezes, ele se registra na sessão SSH:

       NAME    PID     EXECNAME   INO OPS/S    BYTES
socket.send   2655         sshd  7480     1       96
socket.send   2655         sshd  7480     1       96
socket.send   2655         sshd  7480     1       96
...

Existe um script muito mais complexo nos exemplos: link

Aviso

O SystemTap é um software em nível de kernel em desenvolvimento, então existe a possibilidade de panes ou congelamentos do kernel. No entanto, é muito raro, mas tenha cuidado com isso.

Referências

  • link - Página inicial de um projeto
  • link - Wiki
  • link - Tapset de soquete usado em um script de demonstração
  • link - Referência de idioma do SystemTap
por 06.02.2015 / 02:21