Visualizando vários fluxos de dados do aplicativo

0

Estou executando o Ubuntu LTS mais recente e escrevi um aplicativo que faz interface com uma máquina. A máquina possui vários sensores e vários loops PID para controle de temperatura. Os dados chegam muito rapidamente, cerca de 20 leituras / segundo. Durante o teste, gostaria de ter acesso a cada um deles como fluxos separados. Dessa forma, posso organizar alguns terminais para uma visão 'master' de tudo o que está acontecendo.

Minha solução atual é apenas ter arquivos para cada fluxo e fazer com que o aplicativo anexe o arquivo necessário à medida que a leitura é feita. Então eu simplesmente insiro um comando como 'tail -f /tmp/pressure.log' e estou pronto para ir.

São dados descartáveis, por isso estou colocando-os no / tmp para que sejam limpos. Mas isso é um lance de gravações e o tamanho do arquivo pode ficar enorme. O ideal seria que o aplicativo escrevesse em algo no / dev que eu possa seguir exatamente como estou fazendo.

Então, qual é a melhor maneira de ter um texto de fluxo de aplicativo que possa ser visualizado em um processo separado? Idealmente, gostaria de fazer o menor número possível de alterações no meu aplicativo. Obrigado a todos!

    
por Steve Potter 30.07.2015 / 21:01

2 respostas

1

A maneira normal do UNIX de transmitir dados de um aplicativo para outro sem salvá-lo permanentemente é um canal. No shell:

data-producer | data-consumer

Você sempre pode usar pipes nomeados para padrões mais complexos do que um único emissor emissor e um único consumidor recebendo:

# Set up the pipes
mkfifo /tmp/pressure.fifo
mkfifo /tmp/temperature.fifo

# Start the emiters
monitor-pressure >/tmp/pressure.fifo
monitor-temperature >/tmp/temperature.fifo

# Take input from multiple places
collect-and-analyse-all-data /tmp/pressure.fifo /tmp/temperature.fifo

Pipes (sejam regulares sem nome ou nomeados) têm algumas desvantagens neste contexto:

  • Antes de o consumidor executar ou se preparar para ler dados, o produtor bloqueará, ou então o canal armazenará dados em buffer até um ponto e, em seguida, bloqueará. Para um registrador de dados, pode ser melhor descartar dados quando não houver ninguém ouvindo, em vez de armazená-los em buffer ou bloquear o processo. Depende da sua aplicação.
  • Se o consumidor parar de executar ou fechar o pipe, o produtor receberá um erro ao tentar gravar no pipe. Isso faz com que programas ingênuos sejam anulados. É possível ignorar o erro e continuar tentando até que um consumidor abra o canal novamente (possível somente com pipes nomeados), mas você precisa fazer mais trabalho para que isso aconteça.

O UNIX é rico em mecanismos de IPC e você também pode escolher dentre vários outros:

  • arquivos temporários que crescem sem limite (isso soa como o que você está fazendo agora)
  • arquivos temporários cujos dados são constantemente substituídos pelo item de dados mais recente. Simples, mas frágil, caso o consumidor não tenha tempo de ler um item de dados antes de ser substituído.
  • arquivos temporários que crescem até um ponto e depois são rotacionados. Mais trabalho para implementar no produtor e no lado do consumidor para que a sincronização funcione corretamente e não perca itens de dados enquanto o arquivo estiver sendo rotacionado, mas um bom compromisso.
  • memória compartilhada
  • soquetes de datagrama.
  • etc ...

Os últimos dois são difíceis de fazer com scripts de shell, mas o último (datagramas sockets) é pelo menos possível, e é mais fácil se usar uma linguagem de programação como o Python.

Se você está disposto a gastar um pouco mais de tempo e ter algumas habilidades básicas de rede com uma linguagem como Python (ou Ruby, etc ...), então os datalog sockets (UNIX ou UDP) têm muita coisa para eles. Os dados são efêmeros para que não consuma memória, não há nada a fazer para organizar a configuração de comunicação entre produtor e consumidor (basta enviar e receber na porta certa) e, portanto, não há erros para gerenciar quando um ou outro falha ou fica reiniciado, e o produtor e o consumidor podem até estar distantes uns dos outros. A única desvantagem é que os dados vão para o depósito de bits em vez de ficarem armazenados em buffer enquanto o aplicativo consumidor não está em execução.

Mais uma vez, qual solução você escolherá dependerá do seu aplicativo.

    
por 30.07.2015 / 21:35
1

Uma opção seria usar pipes nomeados. Seu aplicativo pode gravar nos pipes nomeados e você pode monitorar os pipes da mesma maneira que você está fazendo atualmente. Você provavelmente desejaria tornar suas operações de gravação no pipe non-blocking, de modo que, se o pipe fosse preenchido, ele não bloquearia a execução do programa. Note, no entanto, que você estaria perdendo dados que não puderam ser escritos.

Veja 'mkfifo' para criar pipes nomeados. Você pode fazer isso programaticamente com o mkfifo (3) ou manualmente com o mkfifo (1).

    
por 30.07.2015 / 21:36

Tags