Python + Fluentd
Autor: Pedro Viana | Publicado: 2015-10-08T00:05:00-03:00


Da ultima vez escrevi sobre fluentd tive foco em ler o syslog do linux, 
interagi também com elasticsearch e kibana. Pois bem, dessa vez vou 
caminhar um pouco para um outro lado. Imagine você que existem aplicações
 em python na mesma instancia que monitoramos o syslog no post anterior. Qualquer semelhança é mera coincidência ;).
 Será que dá para ler também os logs dessa aplicação com fluentd?!  



Caso a aplicação em python seja o foco da maquina, então melhor ainda, pois vai ser possível obter dados de forma rápida de quantas vezes aconteceu algum determinado evento. Isso sem falar do indicativo em tempo real, em formato de histogram que é possível configurar no kibana.



Estendendo ainda mais o assunto fluentd, afirmo que é possível fazer essa interação acontecer de uma forma muito fácil. Encontrei duas soluções para essa questão. Vou admitir que você já tem todo ambiente do fluentd com elasticsearch e kibana funcionando, caso não tenha leia isso antes.



Primeira solução - Fazer com que a aplicação envie os logs diretamente para o fluentd toda vez que ocorrer algum evento. Encontrei no docs.fluentd um exemplo bem interessante que adaptei para mostrar aqui.



Precisamos instalar o fluent-logger, utilize o repositório do pip para isso. Caso não tenha o pip instalado, então leia isso.


pip install fluent-logger


&nbsp;Crie um arquivo de nome python.py e vamos escrever o seguinte nele.


from fluent import sender
from fluent import event
sender.setup('mpdocs', host='10.0.2.15', port=24224)
event.Event('follow', {
 'from':  'userA',
 'to':  'userB',
 'host':  '10.0.2.15',
 'messagem': 'teste para post do mpdocs',
 'ident': 'app1'
})
event.Event('follow', {
&nbsp; &nbsp; &nbsp; &nbsp; 'from': &nbsp; &nbsp; &nbsp; &nbsp; 'userI',
&nbsp; &nbsp; &nbsp; &nbsp; 'to': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'userP',
&nbsp; &nbsp; &nbsp; &nbsp; 'host': &nbsp; &nbsp; &nbsp; &nbsp; '10.0.2.15',
&nbsp; &nbsp; &nbsp; &nbsp; 'messagem': &nbsp; &nbsp; 'mpdocs.blogspot.com.br',
&nbsp; &nbsp; &nbsp; &nbsp; 'ident': &nbsp; &nbsp; &nbsp; &nbsp;'app2'
})
event.Event('follow', {
&nbsp; &nbsp; &nbsp; &nbsp; 'from': &nbsp; &nbsp; &nbsp; &nbsp; 'userI',
&nbsp; &nbsp; &nbsp; &nbsp; 'to': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'userP',
&nbsp; &nbsp; &nbsp; &nbsp; 'host': &nbsp; &nbsp; &nbsp; &nbsp; '10.0.2.15',
&nbsp; &nbsp; &nbsp; &nbsp; 'messagem': &nbsp; &nbsp; 'mpdocs.blogspot.com.br',
&nbsp; &nbsp; &nbsp; &nbsp; 'ident': &nbsp; &nbsp; &nbsp; &nbsp;'app2'
})
event.Event('follow', {
&nbsp; &nbsp; &nbsp; &nbsp; 'from': &nbsp; &nbsp; &nbsp; &nbsp; 'Pedro',
&nbsp; &nbsp; &nbsp; &nbsp; 'to': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'Zeus',
&nbsp; &nbsp; &nbsp; &nbsp; 'host': &nbsp; &nbsp; &nbsp; &nbsp; '10.0.2.15',
&nbsp; &nbsp; &nbsp; &nbsp; 'messagem': &nbsp; &nbsp; 'post sobre fluentd e python',
&nbsp; &nbsp; &nbsp; &nbsp; 'ident': &nbsp; &nbsp; &nbsp; &nbsp;'app50'
})


Para que tudo funcione corretamente o td-agent(fluentd) precisa está configurado de acordo. Repare no codigo acima a porta e também onde está escrito mpdocs. O arquivo /etc/td-agent/td-agent.conf precisa estar configurado dessa forma:


&lt;source&gt;
&nbsp; type forward
&nbsp; port 24224
&lt;/source&gt;
&lt;match mpdocs.**&gt;
&nbsp; type elasticsearch
&nbsp; flush_interval 10s
&lt;/match&gt;


Agora é reiniciar o td-agent, para que o novo conf entre em ação e também executar o python.


/etc/init.d/td-agent restart

python python.py








Segunda solução - Fazer a aplicação escrever o log no syslog do linux. Encontrei no docs.python um exemplo simples que ajustei para demonstrar aqui. Recomendo também a leitura também do docs.fluentd.



Caso queira se aprofundar sobre facilidade do syslog e níveis de prioridade, recomendo a leitura do gnulinuxbr. Em nosso exemplo, uso apenas LOCAL4 ao enviar a mensagem.


import syslog
syslog.syslog(syslog.LOG_LOCAL4, "mpdocs.blogspot.com.br")


Já que vamos usar o syslog, é necessário indicar no arquivo /etc/rsyslog.conf a facilidade utilizada e também a url do fluentd.


local4.* /var/log/app.python.log
local4.* @10.0.2.15:42185


Já o arquivo /etc/td-agent/td-agent.conf, configurei da seguinte forma:


&nbsp; &lt;source&gt;
&nbsp; &nbsp; type syslog
&nbsp; &nbsp; port 42185
&nbsp; &nbsp; tag syslog
&nbsp; &nbsp; with_priority true
&nbsp; &lt;/source&gt;
&nbsp; &lt;source&gt;
&nbsp; &nbsp; type forward
&nbsp; &lt;/source&gt;
&nbsp; &lt;match syslog.**&gt;
&nbsp; &nbsp; type elasticsearch
&nbsp; &nbsp; flush_interval 10s
&nbsp; &nbsp; logstash_format true
&nbsp; &lt;/match&gt;


Depois de ajustar tudo, não se esqueça de rodar o Elastisearch e o Fluentd. Confira abaixo como ficou o resultado. Diferente do primeiro exemplo, que fiz o filtro por ident e no script mudei para fazer um gráfico mais apresentável. No segundo exemplo criei apenas um python de teste e rodei algumas vezes alterando a mensagem.