Boa. Tem só mais um pouquinho de teoria. Vamos lá falar agora de logs na prática. E aqui, de novo, para garantir, antes de entrar no handzone, eu quero... Vamos fazer um contrato entre você e eu, você que está assistindo e eu aqui, e garantir que a gente está pisando no mesmo terreno de conhecimento. Quando eu falo de logs, o que eu preciso saber antes de começar a implementar? Em outras palavras, o que eu preciso saber antes de me dar mal ou dar algum problema em produção? E eu deveria ter pensado nisso antes. O primeiro ponto que eu quero trazer é não escreva logs utilizando sysout. E aí, deixa eu me corrigir aqui não é no sisalde da aplicação que eventualmente as aplicações bibliotecas vai escrever no sisalde no buffer de sisalde não é isso mas por exemplo no java você tem a função system println system out println ou no javascript você tem console.log ou no .NET você tem, por exemplo, outros componentes, por exemplo, console.writealign o ponto é não use essas funções nativas da linguagem para escrever no log de saída pior ainda se você vai escrever no arquivo, não abra manualmente o arquivo e escreva os logs lá não faça isso não reinvente a roda utilize interfaces da linguagem que você tá utilizando ali utilizem a interface comum daquela linguagem do framework que você vai utilizar porque aí você não precisa se acoplar diretamente uma ferramenta de login você pode adaptar a ferramenta de login sem mexer na implementação do seu código. Imagina ter que, sei lá, porque agora a gente mudou de um fornecedor, saiu de uma solução open source e free para utilizar uma solução paga, agora a gente tem que olhar todas as aplicações, sair instrumentando o código, porque a gente mudou a ferramenta de observabilidade, seria muito ruim a gente ter que fazer isso. Legal? E essas e as interfaces, as ferramentas de login, elas se adequam, se acoplam às interfaces para te entregar uma experiência melhor. Então, você usar a interface, inclusive é um princípio arquitetural, um princípio de, inclusive em orientação a objetos tem esse princípio Que utiliza Interfaces, não as implementações E utiliza as frameworks As linguagens, ou melhor dizendo As bibliotecas que estão disponíveis Para você utilizar Porque elas vão abstrair para você a complexidade E até a formatação dos logs que você vai gerar. Exemplo, se você quer gerar em um arquivo e agora você não quer mais gerar em arquivo, você quer gerar no CISAUT, porque você conseguiu pegar a aplicação que estava no legado e jogar ela, por exemplo, no container, na nuvem, e aí antigamente escrevia, por exemplo, o plain text, agora você quer colocar um JSON, enfim, Agora, se você quer colocar um JSON, enfim, mudar o formato, não faz sentido você fazer por conta, não reinventar a roda. Eu utilizo uma biblioteca que faça isso. E terceiro ponto, padronize o formato de saída. De preferência, em todas as aplicações que você estiver utilizando, sempre utilize um formato padrão. O mais comum é, por exemplo, hoje o JSON, mas se você estiver utilizando, por exemplo outro formato você poderia o ponto do formato é que permite que você busque por campos específicos do seu log ainda mais se você tiver utilizando por exemplo Splunk Elasticsearch ou CloudWatch você consegue fazer uma busca passando um campo específico daquele log então Então, por que eu estou trazendo isso aqui? É importante frisar, porque o seu objetivo é buscar padronização, reuso de conhecimento e remover a complexidade da aplicação. E não é interessante que você traga essa complexidade para a aplicação e sim isole isso e, de preferência, foque na implementação funcional do negócio, da experiência que você quer entregar para o cliente e deixa que a biblioteca resolva isso para você e olhando para esses pontos a gente tem já ferramentas preparadas para você utilizar os apenas Java. Net mas tem para todas as linguagens e frameworks que você utiliza tem uma biblioteca de logo lá você pode utilizar. No Java você tem, por exemplo, SLF4J, que significa Simple Login Fassad. Fassad é um pattern, inclusive, de orientação a objetos que te entrega uma fachada, uma abstração e você utiliza. E o que está atrás dessa fachada para você é transparente. E aí, ela é uma interface apenas, e a implementação de fato fica, por exemplo, na biblioteca Log4J ou Logback, por exemplo, são as mais comuns no Java. Você pode utilizar, de repente, a solução mais nativa, por exemplo, do Spang Framework, se você não quiser customizar. E essas soluções, tanto o SL4J, que é a interface, até a solução de login que você está utilizando, permite uma flexibilidade monstruosa. Permite você configurar se você quer escrever no arquivo, qual o formato de saída daquele arquivo, se você quiser escrever no CISALT, qual o formato, se você quiser escrever no formato JSON. Algumas soluções até mais sofisticadas permitem que você aplique regra em cima do log, por exemplo, fazer algum tipo de mascaramento de dado, enfim, bastante interessante. Para o .NET aqui tem o nlog, o serilog, e tem implementações, por exemplo, a implementação do slf fornet, que é uma variação do ela for Jena para para.net e você também tem um logo forneia fornete que a uma uma adaptação do blog para o dia para o.net e o quarto elemento aqui da você precisa levar em consideração é procure centralizar se possível os logs no único repositório é difícil quando você tem um conjunto de aplicações, setenas, sei lá, milhares de aplicações ali que a sua equipe cuida, utiliza, e cada aplicação é escrevendo em um lugar específico, ainda mais se ela se integra. Então, você perde o controle de rastreadibilidade, não estou falando de tracking, de tracing aqui, estou falando até de nível de log, você perde a rastreadibilidade até o reuso da ferramenta que você está utilizando. E quando você utiliza uma solução centralizada, todos os logs AWS estão indo para o CloudWatch, permite que você faça carries mais sofisticadas, cruzando os logs dessas aplicações numa única carry, num conjunto de carries específicos. Ou seja, a sua experiência vai melhorar muito e a detecção da causa raiz, a descoberta da causa raiz vai ser muito mais o processo, o tempo que você vai levar para descobrir a causa raiz vai ser muito mais otimizado quinto não seja repetitivo e nunca, nunca use uma classe de modo para escrever no log exemplos aqui, você vai escrever toda vez que você chegar a um evento, você quer logar alguns dados específicos da aplicação, e aí já vi casos de a pessoa implementar, o time responsável implementar uma classe de módulo para abstrair alguns campos e formatar a saída do log. Não faça. Você está trazendo complexidade necessária para a aplicação e eu já vi problemas. Por exemplo, a aplicação não era capaz, não tinha implementação da interface de serialização, que é o Serializable do Java. E na hora de escrever no log quebrava e aí de novo, como diz o ditado, aqui foi o rabo abanando o cachorro. foi o rabo abanando o cachorro, né? Porque a intenção era boa de lugar os dados, porém acabou quebrando a aplicação e gerando um problema ruim. Não faça isso, né? Tem outras formas mais sofisticadas de você fazer, e uma delas é o uso de variáveis de contexto ou diagnóstico. No Java tem o que se chama Mapper Diagnostic Context. Não é exclusivo do Java, tem outras ferramentas no .NET, você encontra isso e outras linguagens. E você consegue utilizar o MDC, que é uma interface comum ali, que você consegue enriquecer os seus logs com dados ali de contexto. Exemplo, você quer trazer no log dados, por exemplo, como o nome da aplicação, o host, como o nome da aplicação, o host, o trace ID da aplicação que fez a requisição, de forma que você consiga buscar no log. E aí, pegando o link com o item 4, você consegue buscar todos os eventos de log que aconteceram para aquele trace ID, e aí você consegue identificar a causa raiz muito mais rápido. De novo, não substitui uma ferramenta de trace, mas aqui a nível de log facilita muito identificar a causa raiz muito mais rápido. De novo, não substitui uma ferramenta de tracing, mas aqui a nível de login facilita muito identificar a causa raiz cruzando vários serviços. E o que mais? Algum header específico, por exemplo, que você identificar que precisa, por exemplo, o ID da aplicação que está fazendo a requisição, se o time lá que é responsável pelas telas, pelos canais, precisa entender o que está acontecendo, pode falar, olha, fez a aquisição, aplicação X, consegue olhar e tal, e aí você consegue fazer uma busca mais rápida. E aí você percebe que os assuntos vão se convergindo, porque se você tem um log padronizado que está centralizado e utiliza essas variáveis aqui, utiliza o MDC, você diminui a complexidade da aplicação enquanto aumenta a sua eficiência na busca e identificação da causa raiz. E o sexto aqui não só registra esses dados, registra também a versão da aplicação. Eventualmente em produção pode ser que você tenha uma aplicação convivendo com versões anteriores em um espaço de tempo. E aí vai do seu apetite também. Se você estiver utilizando uma solução de Canary, talvez por minutos você vai ter as versões convivendo ali no mesmo momento. Se você estiver utilizando o Blue-Green, talvez até o tempo seja maior. E aí como você sabe que os logs são exclusivos de qual versão? Ou seja, será que foi depois do deploy? Foi antes? E aí olhando pelo histórico, você consegue correlacionar se aquele erro que aparece, aquele evento específico, aparecia antes nas versões anteriores. Então, trazendo um exemplo aqui, imagina que você tem, especificando aqui, trazendo aqui uma... olhando para essas boas práticas, supondo que você tenha a sua infraestrutura, para simplificar, eu trouxe aqui, vamos supor que você tenha dois data centers separados, ou dois hosts, duas máquinas, buscando balanceamento e resiliência. E aí você vai fazer deploy das suas aplicações, você tem, por exemplo, a aplicação A, e ela tem as instâncias dela, duas instâncias da aplicação A no host X, duas instâncias no host Y, você tem a aplicação B, que ela tem uma instância no host X, uma instância no host Y, e a instância C, por exemplo, a aplicação C, igual a B aqui. Às vezes essas aplicações se comunicam. Então é importante que essas aplicações gerem logs numa solução centralizada, que vai facilitar muito o correlacionamento dos eventos de login cross-aplicação. E para piorar, imagina que nos casos de Bluegreen ou Canary, você tem um processo de deploy aqui, que você tem a mesma aplicação que era A, você tem a A, só que ela tem A1, A2, A3, A4, ou seja, ela está, a mesma aplicação A entregue duas no host x e duas no host y, e o processo de deploy, se estiver utilizando o canary e o blue-green, ele vai afetar apenas algumas, uma porção da sua infraestrutura para não gerar indisponibilidade desnecessária, e aí ele vai aplicar a nova versão em algumas, de acordo com a definição, o critério que você utilizar. Por exemplo, aqui no desenho, você tem a aplicação a V2 aplicada na instância 1, a V2 aplicada na instância 3, mas a instância A2 e A4 ainda para a versão anterior. E aí, eventualmente, você vai ter logs das versões. Então, ter a versão, você pode utilizar o MDC, inclusive. Ter a versão escrita no log pode facilitar muito o troubleshooting para saber se foi problema de versão, se você deveria dar rollback. Então, é importante essa boa prática. E para acabar, mais dois itens. O item 7, evite. Talvez seja óbvio, mas evite. É importante frisar, enfatizar, evite gravar logs, dados que identifiquem os usuários. Você tem a Lei Geral de Proteção de Dados, a LGPD, e aí gravar dados de log pode culminar eventualmente em não estar em compliance com essa regulamentação, ou pior, você pode estar gravando dados sensíveis que alguém mal intencionado pode acabar se aproveitando desses eventos. Ainda mais se você não tiver uma política forte de consulta, de acesso aos logs, por exemplo. Se você tem uma ferramenta de log que você consegue indexar por aplicação, seria interessante que você tivesse até uma camada de acesso para aquele índice de logs. Alguém que você conseguisse pedir acesso, aprovação, enfim, controlar a granularidade de acesso para aquele conjunto de logs que você está enxergando. Porque alguém que tem acesso ao log, aquela ferramenta, que não tem principalmente esse processo de gestão de acesso, pode se beneficiar de dados quem que tem acesso ao logo aquela ferramenta que não tem principalmente assim com certeza processo de gestão de acesso pode se beneficiar de dados que não deveria estar ali aí que você pode fazer uma técnica de mascaramento na dúvida nem logo esses dados evite lugar é outras coisas que pode acontecer é você não tá logando dados sensíveis de cliente, mas estar logando dados muito internos específicos da aplicação da infraestrutura que você está utilizando e aí se aquela infraestrutura tem alguma vulnerabilidade também pode ser um alvo aqui de ataque exemplo, você pode revelar que você está usando a versão X YZ da JVM e é conhecida no mercado, lá no Mitre, por exemplo, nesses sites de controle de vulnerabilidades, que existe uma vulnerabilidade muito forte naquela solução. Então, sabendo que você está utilizando aquela versão da JVM, aquela versão daquela biblioteca X, da JVM, aquela versão daquela biblioteca X, a pessoa mal-intencionada pode se beneficiar e executar algum tipo de ataque. Então, é importante, na dúvida, consulte a política interna, compliance, consulte o time responsável que gerencia, se existe alguma coisa em contrato, consulte também, mas é importante levar isso em consideração antes de você sair escrevendo log de coisas até que não precise. E, por fim, utilize o nível de log apropriado. A maioria dos logs que eu acabo vendo, por exemplo, no dia a dia, é tudo, por exemplo, log informacional, mas tem log que não precisaria ser informacional. E aí, por que é importante isso? logo de erro também mas porque é importante isso é porque eu preciso saber implementar na melhor forma primeiro que é resgatando os últimos vídeos a camada de persistência de armazenamento é um custo barato assim ela tem um custo você sair mandando o log às vezes necessário, que vai ser usado, por exemplo, 5%, 10% das vezes para fazer alguma busca pode não ser tão importante exemplo, se você tem cenários que você consegue reproduzir você pode colocar escrever sempre o log apropriado, por exemplo o login, por exemplo, utilizar o debug e na configuração, por exemplo, lá de produção, você dizer, olha, eu só quero logar, eu só quero capturar logs de erro. A aplicação vai continuar a gerar log, mas logs que não são erro, por exemplo, vão ser ignorados. E aí, no caso que você consegue reproduzir o erro, o problema, você pode chavear em alguma variável de ambiente, dizer, olha, agora eu quero capturar também logs de debug de trace você consegue a aplicação vai continuar mandando esses eventos e aí você vai conseguir persistir na camada de persistência por exemplo logs do elasticsearch ou splunk ou outra solução. Usar o componente de log apropriado é importante, até para você conseguir equilibrar o custo versus até ter outro conceito chamado noise, ou enfim, ruído. Se você tem muito log necessário, pode dificultar até seu troubleshooting, ainda mais se ele não estiver seguindo os princípios anteriores. Se você não tem um pattern ali de login padrão de login por exemplo que utiliza o JSON que você consiga fazer algum filtro nossa aí vai ficar vai ficar muito mais difícil você conseguir encontrar a causa raiz no mundo aéreo de eventos que você tá recebendo se você não tiver esse pré-filtro vai ter logs ali que você não vai servir para você, vai mais atrapalhar do que ajudar a causar isso. Então, saber ponderar esse tipo de log é importante também, do ponto de vista de redução de ruídos necessário.