Então, meses sem escrever nada mas hoje estou aproveitando o domingo para escrever algumas coisas sobre o que tenho vivido no último ano. Olhando projeções para o próximo ano, vejo alguns pontos relevantes relacionados ao que posso contribuir com o dia-a-dia de vocês.
Você sabe o que são logs estruturados?
Logs estruturados, diferente dos logs de aplicação, comuns, contém uma série informações e metadados adicionais, usados para agrupamento e consulta. Logs estruturados devem conter informações relevantes ao negócio e ao desenvolvedor.
Um log comum de exceções, por exemplo, envia dados da exceção, como mensagem, stack trace, inner exceptions. Um log estruturado de exceções, poderia conter informações que diagnosticam o servidor no qual o log foi gerado, qual a operação estava sendo processada, qual o ID ou dados mais completos dos seus objetos de negócio durante a operação, além da comum severidade. E não para por aí, ainda seria possível informar qual o cliente da requisição, no caso de WebApps, qual o usuário logado, entre outras diversas informações de aplicação que poderiam ser passadas para o log, ajudando no troubleshooting e análise de problemas ou mesmo de fluxos de negócio.
Como montar uma estrutura eficiente de logs estruturados?
Ao pensar em logs estruturados, um dos primeiros pontos que me vêm a cabeça é a necessidade de metamodelos. A primeira implementação de log estruturado que fiz, foi para a B2W Viagens em 2010, chamava-se LogEngine. Na prática, uma estrutura de log com dados estáticos e dinâmicos. Os dados dinâmicos eram as tags, que diferente do modelo comum que vemos por aí no mercado, oferecia Tag/Valor, em uma estrutura bem simples de Chave/Valor. Nessas chaves você poderia adicionar qualquer informação, nos valores a mesma coisa acontecia. Para que as aplicações não fossem oneradas em virtude da necessidade de persistência desse log, passei a publicar esses logs em filas no MSMQ e posteriormente no RabbitMQ, assim que o Oragon começou a dar suporte ao RabbitMQ. A publicação de mensagens de log nas filas do RabbitMQ foi o primeiro motivador para a implementação dessa feature no projeto.
A persistência desse modelo acontecia em banco relacional e aí começaram os problemas. Embora seja extremamente eficiente do ponto de vista de armazenamento (nenhum dado semelhante era duplicado), a performance de consulta e escrita não eram satisfatórios para a massa de dados que eu estava trabalhando.
O Log Engine não existe mais, mas era um projeto bem interessante, pois permitia que os desenvolvedores vissem seus logs, em tempo real, mas ainda usando queries em banco, e muitas vezes queries bem complexas.
Ferramentas de Suporte
O projeto não chegou a virar produto por falta de um time de desenvolvimento. Basicamente hoje o mercado está cheio dessas soluções, mas na época, apenas existia o Oragon Architecture e o LogEntries. Alguns anos depois, já na iMusica, fui apresentado ao Sentry, e posteriormente ao LogStash/ElasticSearch/Kibana. Bom o Sentry é uma ferramenta bem interessante, mas tuná-lo é uma tarefa bem chatinha. Sofri alguns meses com o Sentry, principalmente com a perda de mensagens. Por padrão o Sentry é passivo, portanto você precisa publicar as mensagens nele. O protocolo padrão é HTTP e usamos o Raven para executar a tarefa. Diferente do modelo padrão, onde a aplicação chama diretamente o Sentry, nossas mensagens eram enviadas para o RabbitMQ, e posteriormente outro serviço se encarregava exclusivamente de publicar essas mensagens no Sentry. Essa mudança no viés exige que se faça uma mudança simples no Raven para que a data da mensagem não seja adicionada no momento em que a mensagem está sendo publicada no Sentry. Sua mensagem que estava na fila já possui essa informação, e você pode ter um delay entre uma tarefa e outra.
Outro produto que estou usando mais agora é o ELK, acrônimo para ElasticSearch, LogStash e Kibana. Enquanto o ElasticSearch é um backend NoSQL, baseado no Lucene, com uma API REST de escrita/leitura, e uma API muito robusta de consulta, já o LogStash é um serviço de coleta de logs ativo, responsável pela leitura e transformação de logs e sua publicação. No modelo ELK o LogStash publica os logs no ElasticSearch, mas tem a capacidade de publicar os logs em outros backends e tecnologias. Há uma abstração bem clara entre o que ele chama de input e output. Além da leitura e escrita, ele possui capacidades de transformação de logs, e converte logs nos mais variados formatos de origem e destino, é excepcional! Por fim o Kibana é um dashboard html+javascript extremamente configurável e robusto que conversa direto com o ElasticSearch. Esse é o padrão que utilizo hoje.
Conslusões
Uma das grandes vantagens desse modelo, é eliminar a necessidade de implementação de mecanismos de leitura das filas (RabbitMQ) e publicação no backend de log. O LogStash faz essa tarefa graciosamente. O ElasticSearch é extremamente robusto e suporte uma massa de dados infinita, com suporte a clustering, charding, e muito mais. O Kibana poderia ser melhor, ter mais funcionalidades, mas já oferece muita coisa interessante.
Outro ponto bem interessante desse modelo foi a eliminação de tabelas de log do meu modelo de domínio. Como meus logs são bem estruturados consigo manter uma boa rastreabilidade com base nas tags e em seus valores, permitindo além de consultas diretas, ser chamado direto a partir de interfaces Web, usando HTTP, desde que seu ElasticSearch possua conectividade. De qualquer forma há API`s para .Net, oferecendo suporte Server Side.
Bom, é isso, se tiverem dúvidas sobre logs estruturados, é só comentar ou mandar uma mensagem!
Obrigado pessoal.
0 comentários