Um amigo me perguntou hoje sobre soluções NoSQL. Na conversa que se seguiu, descobri o que ele precisava fazer: precisa publicar um servidor cujas URLs vão simplesmente fazer um redirect para outro site, mas devem guardar as informações do redirect para enviar para o Clicky. É claro que os dados devem ser enviados ao Clicky o mais rápido possível, para que as estatísticas sejam atualizadas e o cliente do meu amigo possa acompanhar as estatísticas em tempo real. Mas o mais importante é que o redirect seja feito rapidamente, e que o serviço aguente tráfego massivo.
Meu amigo pensava em usar nginx com PHP e uma solução de NoSQL. Eu expliquei a ele que era uma ideia mais complicada do que precisava. O ideal, nessa situação, é dividir os problemas. O nginx poderia sozinho cuidar dos redirects, sem PHP, com uma performance impressionante. E ele poderia em seguida fazer algo que lesse o log do próprio nginx e enviasse os dados dados ao Clicky.
Meu amigo programa bem em PHP, então vamos fazer oq ue pudermos nessa linguagem. Veja um exemplo simples de como isso funcionaria: podemos criar um shell script simples que vai simplesmente executar um tail -f no log do nginx e redirecionar a saída para um script PHP.
O comando tail -f é muito interessante. Deixe uma janela de terminal aberta em seu Linux com:
tail -f /var/log/syslog
Você vai ver que o tail, com -f, imprime o final do arquivo mas não sai. Ele fica monitorando o arquivo e quando novas linhas são acrescentadas, ele as envia para a saída padrão (nesse caso, a tela.)
Então nosso shell script, chamado monitor.sh, terá o seguinte conteúdo (troque o caminho do arquivo de log pelo caminho onde ele fica em seu sistema):
tail -f /var/log/nginx/access.log | php monitor.php
Isso vai manter o script rodando, enviando cada nova linha no log para o monitor.php. Cada vez que o nginx processa uma requisição ele envia nova linha para esse arquivo. O monitor.php pode ter algo assim:
<?
$stdin = fopen('php://stdin', 'r');
while($l=trim(fgets($stdin))){
// Aqui $l contém uma linha do log do nginx.
// Faça o que quiser com isso. Como exemplo
// vou só tratar os dados e imprimir.
$l=split(';',preg_replace('/( |\t)+/',';',$l));
$l[3]=substr($l[3],1);
$l[5]=substr($l[5],1);
if($l[5]=='GET' or $l[5]=='POST')
echo "$l[0] $l[3] $l[5] $l[6]\n";
}
Por fim, falta deixar isso rodando. O jeito mais simples é deixar uma sessão de screen aberta com o comando. Basta rodar o comando screen, executar o monitor.sh no shell que vai se abrir e sair com CTRL+D. Claro que há jeitos melhores de deixar isso rodando. O ideal é transformar esse script num daemon. Mas a solução com screen é suficiente para iniciar no assunto.
JABÁ: para entender melhor os detalhes e aprender mais truques como esse, vá ao Workshop de Linux para Desenvolvedores.
View Comments (3)
Elcio, finalmente tive uma demanda em que foi necessário ler os logs, entretanto, tive problemas com o logrotate, pois, o o "tail -f" fica ligado a um ponteiro de arquivo, pesquisando a documentação eu descobri a solução simples: "tail -F" (F maiúsculo), assim, ele fica verificando se o arquivo foi renomeado ou não... e quando ele é rotacionado o tail passa para o novo arquivo de log "automagicamente"
Bom, ja estou com um script rodando a 1 semana coletando dados de log e jogando no mongodb e está tudo funcionando perfeitamente.
Obrigado.
Olá Elcio!
Uma alternativa ao screen é usar nohup:
nohup &
Ele evita que o sistema envie o sinal de hang up, terminando o comando ao sair do terminal.
Esse seu jabá é muito importante, por mais absurdo que possa parecer tem muito desenvolvedor que programa e não conheço muito sobre o sistema operacional que vai rodar seu software.