Olá, vamos continuar, nós paramos no passo 3 e agora vamos implementar o passo 3 completo, vamos copiar todas as dependências que a gente precisa, vamos colocar lá no .xml, vou substituir, acabei se perdendo nas duas, já tenho ela baixada também no log encoder, e essa é a biblioteca do logstash Encoder, vamos utilizar para formatar como JSON. Deixa por enquanto, a gente só vai usá-la lá no final, quando de fato a gente aplicar o passo 5 de novo. A gente só vai referenciá-la aqui para não deixar passar. Uma outra boa prática importante é o uso do MDC. Eu comentei entre as boas práticas que não é interessante você ficar parametrizando ficar parametrizando classe de modelo para abstrair, encapsular alguns campos para você exibir no log, ainda mais se tornar repetitivo. É muito ruim, você vai trazer complexidades necessárias para a aplicação. Existe um conceito do MDC e o MDC pode ajudar muito a gente aqui a capturar dados de contexto. Por exemplo, imagina você no ambiente distribuído, onde você tem milhares de aplicações e você quer rastrear todos os logs de determinada requisição. Você pode incluir no MDC, por exemplo, um trace ID que veio do header. Pensando em boa prática também, imagina que a aplicação está rodando no ambiente de produção, no ambiente containerizado, enfim. E você pode ter várias instâncias daquela aplicação rodando simultaneamente. Quando a aplicação morrer, eventualmente ela vai ter uma vida útil de horas, às vezes até minutos, de repente, sei sei lá finalizar inesperadamente é importante você ter alguma informação no log para você conseguir resgatar de qual host de qual enfim qual os metadados aquela do host daquela aplicação o container estava executando aqui eu tô pegando o host no header mas eu poderia pegar uma informação do container especificamente e acrescentar no mdc a importante aqui também tô colocando o nome da aplicação porque de novo vocês vão utilizar ambiente centralizado para vários inúmeros logs é importante que você consiga diferenciar logs de aplicações específicas, a versão da aplicação, tão importante quanto, principalmente quando você estiver aplicando um deployment de Blue Green, Canary, você conseguir saber qual versão aquele log está gerando, e até a data de build daquela aplicação. Apenas isso para a gente testar, e como que eu vou fazer isso? Tem duas formas de fazer o uso do MDC a primeira é quando você tem uma aplicação batch, uma aplicação worker exemplo, uma aplicação que você roda a esquerda do lado ela chama o jar, ela chama o main da aplicação e ela roda um conjunto de rotinas depois ela finaliza ou você tem uma aplicação que fica rodando sempre escutando tem uma aplicação que fica rodando tem sempre escutando ali tem uma prédio ficar escutando o próprio de uma fila de um tópico cá fica por exemplo é você precisa colocar fazer esse enriquecimento de merecer aqui ó é uma interface que chama classe put e passa chave valor esse enriquecimento você precisa fazer num ponto de entrada, e aí vai para a configuração que você entender. Do meu ponto de vista, essa configuração precisa ser feita no primeiro ponto de contato com a sua aplicação, na lógica que você está implementando. No caso, o worker, no main ali, ou no ponto de contato quando ele recebe a mensagem da fila, naquele momento você poderia ou deveria incluir usando o MDCPut esses dados de contexto. Agora, numa aplicação web fica um pouco mais difícil, porque às vezes numa aplicação web você vai acabar recebendo uma requisição no controller e vai passar por várias etapas e como fazer garantir que todos os controles implemente o MDC pote você tem que ficar repetindo o código em todos os controles é a forma mais interessante de se fazer por exemplo no Spring e acho que ano e isso em que vai também para outras outras fêmeas como por exemplo.NET, Core, .NET Framework, você tem o Request Lifecycle. No Request Lifecycle do Spring, você tem o Handle Interceptor. Ele consegue interceptar todas as requisições, fazer o cadastro, o enriquecimento do MDC e retornar true ali para que o Spring passe para o próximo interceptor e assim por diante. Então, como que a gente implementaria isso no Spring? Vamos lá. Aqui na nossa aplicação vamos utilizar esse mesmo trecho de código, vamos criar uma classe chamada, vou chamar com esse nome aqui, request MVC interceptor, vamos vermdc-interceptor, vamos ver se eu já não criei, se não a gente cria agora, acho que já está aqui. Então eu tenho aqui implementada o request-mdc-interceptor. O nome poderia ser outro, eu chamei de mdc-interceptor porque é para eu saber que é um interceptor específico pra uso do MDC. Mas você poderia ter outros interceptors inclusive de segurança, por exemplo, se você não tiver utilizando uma biblioteca específica desse, security, que vale de autenticação e autorização, você poderia implementar de forma caseira um interceptor que vale de ser que você tá vindo com authorization token, por exemplo. Aqui eu implementei que está praticamente igual, a diferença é que em vez de utilizar o auto-irid aqui, eu estou utilizando eu estou passando como argumento o build-property que está vindo com o required-args constructor. Eu vou falar desse build-ósito já já e aí eu implementando aí o resto a mesma coisa a implementação é igual aqui e a classe de configuration porque só criar um não é suficiente preciso criar uma um config um configurer né? Um configurer ou algum configurer que consiga pegar a lista de interceptors oficiais ali do SPENG que ele tá utilizando e cadastrar, adicionar o seu interceptor. Então aqui eu também implementei, de novo utilizando o required args constructor, utilizando o recorde o que você acha que eu fiz eu não tô deixando do bloco no target classes no store confie vou pegar aqui o adaptador confie ele vai criar para gente aqui ó um um construtor gerada que automaticamente com o nome da classe o o o atributo que está recebendo aqui na requisição e o valor. Então, só para facilitar, e aí o Spring identifica que tem que injetar esses componentes no construtor na hora de instanciar a classe. E aqui eu estou pegando a lista e estou adicionando no registry que está vendo aqui o meu MDC Interceptor. Esse MDC Interceptor é o que eu criei lá e estou adicionando no registry que tá vendo aqui o meu MDC Interceptor. Esse MDC Interceptor é o que eu criei lá e eu tô adicionando aqui, depois eu sigo em frente. Se eu tivesse outros interceptors, eu colocaria aqui nessa lista, tá? Pois bem, esse build properties, ele é uma classe aqui do Spring Boot Info, mas ele precisa de um arquivo que só é gerado no tempo de compilação e eu preciso ainda fazer uma adaptação, que é aqui no build, aqui na etapa aqui do build, do maven, lá no .xml, vamos abrir o .xml, na etapa do ma do meio eu tenho esse executions eu tenho aqui ó spring boot mesmo plugin e dentro do espelho espreito provavelmente viria sem né tem mesmo plugin e aí eu inclui aqui esse aqui o churros execution aí de executions, executions, id buildinfo e goals buildinfo. O que isso aqui faz? Se eu vier aqui clean install, clean ou compile, enfim, eu vou fazer o install já. Se eu fizer o clean install, esperar ele terminar aqui. vou pausar e assim que terminar eu volto boa, demorou um pouquinho, finalizou a partir do momento que eu rodo o maven para compilar as classes aqui, por exemplo, dentro do jar tem aqui um cache aqui dentro do jar, ele vai ter nessa estrutura, por exemplo exemplo classes meta-env build info properties e aqui eu tô capturando os dados da aplicação como build group build name o artifact o time que foi compilado e a versão e aonde tá essa informação no pom mesmo se eu subir aqui no pom xml ele tá pegando a informação que está aqui. Então, se eu mudar de versão, por exemplo, chamar de versão 0.2, sem snapshot. Vamos ver se com clean compile vai rodar, senão eu vou ter que usar outras etapas. Vou pausar o vídeo de novo para encortar. Foi. Foi rápido dessa vez. Vamos ver se ele gerou. Build Info. Aí, gerou o Build Version 2 sem o snapshot. E essa informação que ele vai capturar na hora de informar aqui no MDC se esse arquivo, importante, se esse arquivo não existir vai dar erro de injeção aqui, porque o build properties ele vai carregar, vai procurar o arquivo ele não vai encontrar o arquivo e se não encontrar ele vai dar algum erro e aí esse arquivo precisa ser gerado então, eventualmente eventualmente local se você implementar no pão e não compilar primeiro ele vai dar o erro então apenas faço o o meio vim com paio ele vai gerar para você o arquivo e é ainda sem avançar vamos vamos vamos testar a etapa vamos testar a etapa 4 ainda, com a inclusão dos atributos de MVC. Vamos voltar lá no logback, porque é no logback que a gente precisa incluí-los. Vou incluir aqui no console mesmo, para ganhar tempo, como que eu referencio uma variável do MDC. Eu referencio passando símbolo de percentual certo simbolo de percentual x o x é uma variável que carrega os dados do MDC vamos fazer um teste vou rodar vou desativar que o file aprender só para não ficar gerando também necessariamente. Ah, deixa ele aberto aqui mesmo. Eu não coloquei no File Appender. Vou colocar lá, vou dar um play. Vou colocar só no File Appender. Ele vai gerar agora o log. Por enquanto ele não vai gerar nesses logs de inicialização do Spring, porque ele não passou gerar nesses logs de inicialização do Spring porque ele não passou por aquela etapa e como eu estou fazendo o intercepto eu preciso fazer uma requisição HTTP para que ele apareça ali, então vamos fazer aqui uma requisição HTTP, vou deixar aqui lado a lado vou fazer uma requisição por exemplo, o método post aqui ele gerou o log, vou fazer mais uma, e vou fazer uma consulta. Gerou os logs, vamos abrir aqui agora para a gente olhar, e observe que ele gerou aqui, ó, tudo que eu tinha colocado no mdc ele colocou para mim, ó, trace, o id da requisição, que id da requisição é essa. No insomnia, eu parametrizei um header é uma configuração do header e eu tenho um atributo no insomnia aqui, por exemplo, do orders por isso que na requisição veio nulo aqui, porque eu acabei não parametrizando mas eu tenho xtraceid, xtraceid e aí eu tenho um elemento que gera um um gid, um gid pra mim, aí ele vai colocar aqui na requisição subsequente que eu chamei não vem tá porque eu não coloquei na requisição poderia ter um interceptor que obrigasse a implementação desse reto aqui eu tô passando host o hotel é ele é ele é obtido dinamicamente mas aí o ins Insomnia fez a aquisição com essa informação. A versão da aplicação que a gente acabou de tirar, a data de geração daquele build e o nome da aplicação. Pode não ser muito útil, mas se você quisesse, por exemplo, formatar e até referenciar uma variável específica, exemplo, eu quero colocar no log apenas o trace ID, o trace ID e, por exemplo, o app version. Como que eu referencio? Você pode colocar aqui no %x, símbolo de percentual, pode consultar inclusive a documentação do logback, você pode colocar trace id, que é o nome, exatamente, tem que ser exatamente o nome, e eu tenho quase certeza que ele é case sensitive, não testei, mas ele provavelmente é case sensitive, tem que ser exatamente o nome que você criou lá no MDC, a chave no MDC. E, de novo, símbolo de percentual, abre chaves, aí você pode colocar app version. Você pode colocar algum tipo de separador, por exemplo, vou tentar colocar um pipe aqui para ver se ele vai entender. E eu vou colocar antes, e vou colocar aqui por traço, e aqui vou colocar depois. Vamos ver se ele vai conseguir interpretar. Vou parar a aplicação, vou executar de novo, e vamos testar opa, ele não provavelmente ele entende que o pipe ele é um atributo ah não, ele está reclamando do da chave aqui, ah porque eu esqueci de passar o x aqui, né, então deixa eu corrigir, símbolo de percentual x a chave aqui. Ah, porque eu esqueci de passar o X aqui, né? Então, deixa eu corrigir, símbolo de percentual X a chave. Então, valeu aqui na configuração. Vamos dar um play de novo, esperar a aplicação subir. A aplicação subiu, vamos fazer agora uma requisição em Palavra Insomnia, vamos fazer agora uma requisição em Palavra Insomnia, vamos fazer a mesma requisição e... Voilá, apareceu apenas a chave e a versão. Tá, mas aí não apareceu nenhum valor, você pode customizar e colocar a chave, não apareceu a chave, o nome do campo, mas você pode colocar e implementar seguindo a documentação do logback. Então, o que eu quero enfatizar com o uso do MDC é que eu não mexi em nada no log da aplicação. Se eu vier aqui no main, Java, ou o crawler, eu mexi na minha aplicação. Meu login continua do mesmo jeito o debug continuou do mesmo jeito se essa aplicação não tivesse código fonte, mas eu tivesse apenas o jar, o binário se eu estivesse implementando as bibliotecas necessárias eu poderia apenas customizar o logback sem mexer no código da aplicação e ele conseguiria capturar para mim todos os eventos necessários e inclusive o se ela tiver logando os dados do MDC eu não preciso me preocupar, observe que eu facilita muito a vida aqui na hora de carregar esses dados de contexto e todo log vai exibir essa informação então eu não preciso ficar repetindo no código esses dados sempre ele vai sempre aparecer