Boas-vindas ao curso de Confiabilidade: garantindo o stado de Integridade de sistemas através de logs. Sou o Kleber Costa e serei o seu instrutor ao longo deste curso.
Este primeiro vídeo é introdutório, para você entender sobre o que se trata o curso e sobre o que será aplicado. Vamos ao sumário entender os tópicos deste vídeo.
Vamos ao primeiro tópico. A aplicabilidade deste curso se destina às seguintes pessoas:
Isto é, pessoas da área de tecnologia que tenham uma atuação técnica. Mesmo que você não esteja em uma dessas áreas, mas queira fazer parte de alguma delas, este curso vai agregar bastante conteúdo e te dar uma boa direção. Dado que este assunto é fundamental para o desenvolvimento de qualquer produto ou sistema.
É preciso que você possua conhecimentos básicos de Java, de Maven e Spring Boot. Se possuir conhecimento sobre Java e Maven, já vai conseguir lidar com Spring Boot com bastante facilidade.
É fundamental também, que você saiba como tratar estruturas condicionais. Saber o básico de Docker e já tê-lo instalado na sua máquina e, conhecer sobre o Docker Compose.
Se estiver usando o sistema operacional Windows, o executável do Docker já traz o Compose junto. Caso use o macOS ou Linux, é preciso que conheça o Docker voltado para o sistema operacional que possui na sua máquina. Isso porque há algumas mudanças de configurações, principalmente em arquivos do Docker Compose para o macOS.
Basicamente são esses os requisitos para você realizar este curso sem ter muitas dificuldades.
No primeiro capítulo vamos apresentar os problemas de uma aplicação sem log e qual o impacto que isso gera em um time de desenvolvimento. Isso vai envolver termos como MTTD (Mean Time To Detect ou, em português Tempo "Médio de Detecção"), MTTR (Mean Time To Response ou, em português "Tempo Médio de Resposta") e análise de causa raiz.
Logo, vamos tratar de problemas que enfrentamos ao identificar incidentes ou situações de degradação que vão gerar incidentes. As dificuldades que possuímos em não ter registros específicos sobre os eventos da aplicação e como isso impacta no tempo de solução de um problema e, principalmente, como impacta na análise de causa raiz, no RCA.
No segundo capítulo, trataremos as boas práticas de Logging. Isto é, o que um log precisa para nos auxiliar nas dificuldades apresentadas no primeiro capítulo. Na terceira parte aprenderemos sobre os níveis de Log e sua hierarquia, como implementamos na prática. Como usufruímos desse tipo de organização hierárquica.
No quarto ponto, abordaremos sobre a refatoração, vamos reestruturar o nosso modelo de logs. Visto que neste ponto já teremos feito o log em stand out put, log em disco, trabalhado com políticas de empacotamento, compactação e rotação.
Por fim, reestruturaremos para um modelo de uma API, uma aplicação vai ser containerizada e escalada horizontalmente. Ou seja, não é recomendável escrever em disco, vamos refatorar tudo para deixar nesse modelo. Porém, não deixaremos de dar atenção para situações de ambientes legados, em que essa prática é comum.
Em seguida, entraremos na situação de tratamento de exceções com o log sendo utilizado. E também, no momento de responder um cliente com um código mais leve, não retornando um stack trace.
No último capítulo teremos um log estruturado em JSON — um formato amigável e espero por alguns softwares que operam como centralizadores de log e nos auxiliam no trabalho com os dados coletados. Ferramentas como o Elasticsearch, o Planck, o Grafana Loki, o Graylog e assim por diante.
O nosso objetivo é preparar essa aplicação para utilizarmos o Grafana Loki. Logo, no final do curso já estaremos com um log bem estruturado com uma aplicação tratada com log. Pronta para realmente centralizar os logs em uma aplicação, colhendo os benefícios dessa implementação.
É fundamental sabermos que o log é um evento. Isto é, quando nos referimos a registro de eventos significa que vamos realizar o armazenamento de uma informação. Esta precisa conter um nível de explicação que leve qualquer um que for fazer uma análise sobre o registro ao entendimento completo sobre o evento.
Todo evento importante para a aplicação precisa ser registrado em forma de log. Logo, é necessário compreendermos o que um log oferece. É indispensável que ele possua data e hora do evento, que seja armazenado e tratado como registro imutável — visto que não vai nos auxiliar somente na hora de um troubleshooting, também é um registro auditável.
Isso significa que serve para uma auditoria, para responder por um questionamento legal, em alguns casos. Por isso, é importante que o log seja tratado, armazenado, que tenha uma política de retenção e que seja cultivado como registro imutável.
O log oferece rastreabilidade em termos de execução. Dado ser possível, através de um log estruturado, entender qual o caminho de execução de uma funcionalidade nas regras de negócio. Afinal, quando chamamos a rota, qual o caminho que a aplicação percorre para processar determinada requisição? É o log que entrega isso.
O nível de severidade que o evento possui é outra característica mandatória do log. Isso para informar se é um evento crítico, um erro, um aviso ou é só uma informação. É possível trabalhar com o nível para depurar a aplicação, realizar um debug ou fazer uma rastreabilidade no beach, usando um trace.
Um trace em termos de log, não confunda com rastreamento pilar da observabilidade.
Agora que já vimos o que um log precisa oferecer, vamos aprender o que ele deve possuir.
O primeiro ponto é possuir um código do evento executado, o segundo é ter uma mensagem personalizada em alto nível. Este para que a pessoa escalada para dar suporte a produção, consiga entender de uma forma simples o que aconteceu.
A condição tratada no caso de uma exceção e, também, um período de retenção especificado. Seja para um log escrito em disco, isto é, para um armazenamento em uma aplicação ou software de centralização de logs.
Esses são os aspectos que devem constituir um log.
Vamos entender agora qual o ambiente do curso. É necessário que você tenha o Docker com o Docker Compose instalado. O Docker vai ser responsável por cuidar de um container, um database. Sendo a dependência de conexão, a camada de persistência de dados.
A aplicação é em Java 11, é preciso que tenha o OpenJDK 11 ou outra versão do Java 11 instalado e o Maven também. Consumiremos essa aplicação usando o Postman, e vou usar a IDE Eclipse, mas você pode usar a que preferir.
A nossa aplicação já possui uma camada de observabilidade implantada. Ela tem o Micrometer, que serve para a exposição de métricas, logo é um facade
que funciona pegando as informações do Actuator. Este é a camada de externalização de métricas da JVM (Java Virtual Machine ou, em português "Máquina Virtual JAVA").
Vamos configurar de forma correta o SLF4J e o Logback, recursos nativos do Spring Boot, para termos uma camada madura de logs. Com logs estruturados e com as regras de negócio da aplicação implementadas da forma correta. Isso para que futuramente seja possível centralizar os logs no Grafana Loki.
Esse é o nosso objetivo, basicamente esse é o ambiente do curso.
São essas as informações que queria passar para vocês neste vídeo, espero que gostem e que este curso agregue valor na sua trajetória. Te vejo no próximo vídeo!
Neste vídeo vamos configurar o ambiente, gostaria de já informar que utilizo o Linux. É importante que na plataforma, em "Downloads de arquivos", você baixe o arquivo .zip
com o conteúdo da aula e o descompacte na sua máquina.
Após descompactar, teremos o diretório api-logs
, clicaremos duas vezes nele com o botão direito do mouse. Dentro desse diretório, encontraremos alguns outros diretórios, que são:
O logs
, o postgres
, em que estão os arquivos necessários para o build do container Postgres, e o docker-compose.yml
, em que está o código responsável para que o Docker consiga buildar o container do Postgres e subir o database.
Em seguida, vamos abrir o Eclipse e após descompactar o pacote do arquivo .zip
, é necessário importarmos o projeto. Para isso, do lado esquerdo da tela em "Package Explorer", clicaremos na terceira opção "Import Projects".
Vai abrir uma tela com o título "Import" em que selecionaremos a pasta Maven
, vai ser exibido algumas outras opções em que escolheremos a "Existing Maven Projects" (em português, "Projeto Maven Existente"). Em seguida, vamos clicar no botão "Next" na parte inferior central.
Na tela seguinte, com o título "Import Maven Projects", para passarmos onde está o projeto, selecionaremos o primeiro botão "Browse" do lado direito, o path (em português, "caminho").
Novamente vai exibir uma tela com o título "Select Root Folder". Clicaremos na pasta api-logs
, em seguida, no diretório logs
, dentro deste temos um arquivo pom.xml
que vai ser identificado pelo Eclipse como pertencente a um projeto Maven. No canto superior direito da tela, vamos selecionar o botão "Open".
Note que na tela "Import Maven Projects" em "Projects" já foi encontrado o pom.xml
. No canto inferior direito dessa tela, pressionaremos o botão "Finish". Com isso, vai retornar para o Eclipse. Perceba que do lado esquerdo, em "Package Explorer", vai ser exibida a pasta logs
.
Vamos clicar na seta ao lado esquerdo da pasta logs
para expandir. O Eclipse pode demorar um pouco para baixar as dependências e configurar o projeto como Maven. No meu caso, já apareceu, visto que o projeto já estava importado e eu o excluí para refazer o processo de importação com vocês.
O ideal é aguardar um pouco para baixar as dependências. Inicialmente, perceba que no seu pode não ter todos esses arquivos configurados, igual consta no meu, dado que são gerados conforme as dependências do Maven são baixadas e configuradas.
Após esperar as dependências serem baixadas, em "src > pom.xml", na pasta pom.xml
, clicaremos com o botão direito do mouse. Vai abrir um menu e nele selecionaremos "Maven" e, em seguida, "Update Project". Exibirá uma tela com o título "Update Maven Project", isso é só por descargo de consciência, logo apenas pressionaremos o botão "Ok", do lado inferior direito.
Dessa forma, já estamos com o projeto configurado. Temos um projeto usando Maven, separado em pacotes, conforme podemos observar na "src/main/java"
. Esse projeto é uma API Rest, que possui a funcionalidade de gravar as informações dos novos cursos na Alura. Como funciona?
Vai ter um curso novo que vai ser rodado, executado e construído. Precisamos armazenar as informações desse curso como, quem é o instrutor(a), quais os conteúdos, quais as dependências, a carga horária, a categoria que se encaixa. Basicamente, é isso que faz essa API Rest.
Expandindo a pasta "src/main/java"
, clicaremos na primeira opção "br.com.alura.logs"
, vai ser exibido o arquivo "CursoApplication.java"
. Este é o pacote principal da aplicação, logo é essa a classe em que temos que executar para que a aplicação suba. Ela que é o application do Spring Boot.
Porém, antes de fazermos isso, é necessário subirmos o banco de dados. Para tal, abriremos o terminal e executaremos o comando cd api-logs/
, para entrarmos na pasta api-logs
.
Comando para executar no terminal:
cd api-logs/
Lembrando que estou usando o Linux, por isso alguns comandos que usarei não se aplicam para você, caso esteja em um sistema operacional diferente. Se estiver utilizando o Windows, pegue a interface gráfica do Docker, sobe ele e garanta que o Docker Compose já esteja configurado. O executável do Windows no Docker, traz o Docker, o Docker Compose e o Kubernetes.
Logo, roda tudo nesse executável do Windows, você vai na interface gráfica e sobe o Docker, caso ele não esteja funcionando. Se estiver no macOS, o ideal é ler a documentação do Docker e do Docker Compose, garantir que estão instalados e subir o serviço no Mac ou configure para subir o start up do Mac. Isso é um pré-requisito do curso.
Voltando, dentro de api-logs
vamos executar o comando de listagem. Note que temos o arquivo docker-compose.yml
, ao rodarmos o cat docker-compose.yml
serão exibidos alguns campos.
Comandos de listagem:
ls
Comando para exibir os campos:
cat docker-compose.yml
O campo "image" é um postgres, o "container_name" (nome do container) é um "database-api-cursos". Se for derrubado como consta em "restart" vai receber um "unless-stopped", portanto ele não sobe sozinho. Há motivos para ser desta forma. Em "healthcheck" temos o teste de healthcheck, não vou explicar esse campo por ser uma informação irrelevante neste curso.
Em "environment" temos as variáveis de ambiente. Quem é o usuário, qual a senha (password), qual o usuário que a aplicação vai usar para se conectar, dado que não é o root que se conecta na base de dados e sim o usuário Alura. Em seguida, a senha do usuário Alura e, por fim, o nome da base de dados que ele vai acessar no Postgres, chamada de "logsbd".
No campo "ports" temos a porta que vai ser rodada,vai ser executado um bind
na porta da sua máquina. Logo, vai subir o container e vai ficar na porta 5432 e executar um bind
na 5432 TCP (Transmission Control Protocol ou, em português "protocolo de Controle de Transmissão") da sua máquina.
Em seguida, em "volumes" são os volumes utilizados para inicialização de criação de tabelas, toda a parte de trabalho no Postgres.
No terminal, em data
não pega nenhuma informação. Mas encontramos em data
o diretório inicial que o Postgres vai usar quando ele popular a base de dados. Mas podemos ficar despreocupados, pois não é uma pasta em que precisaremos acessar.
Porém, dentro de db
, se rodarmos o comando cat postgres/db/01-init.sh
vai ser exibido um SQL feito para ser executado para criar o usuário e fazer as definições corretas para acessarmos a aplicação.
Comando para rodar no terminal.
cat postgres/db/01-init.sh
Para seguir, com o Docker instalado e rodando na máquina, no terminal rodaremos o comando docker-compose up
. Isso para subirmos o container, pode demorar um pouco. Dado que é necessário ele montar e subir o container e baixar imagem.
Note que temos uma linha escrita "CREATE DATABASE", informando que foi criada a base de dados. Analisando mais um pouco, temos um log bem estruturado, com timestamp, com log code e uma mensagem direta e simples de entender.
2022-05-24 13:00:54.053 UTC [1] LOG: database system is shut down
Dessa forma, conseguimos compreender como é importante um log bem estruturado. Voltando para o Eclipse, vamos subir a aplicação selecionando o botão "Run" ("▶") no menu superior da tela.
Perceba que no console do Eclipse, na parte inferior, mostra que está subindo. Houve um problema, explodiu um exception com o log multiline, entre outros erros. Com isso, já entramos no conteúdo do curso. Partiremos do pressuposto que essa aplicação foi desenvolvida pelo seu time de desenvolvimento.
Analisando esse retorno, como você identificaria o problema? A aplicação não possui log definido. Para ir para a produção, essa aplicação precisa ter um log estruturado. Dado que, por padrão, se estiver usando sistem out em algum momento no Java, você já está logando.
Logo, já possui o necessário para realizar um log. Porém, nessa aplicação não temos um log bem estruturado, na verdade, nem uma configuração de uma API de log sendo utilizada.
Observando o retorno no console do Eclipse, temos uma linhando informando "FATAL: database "logs" does not exist". O "FATAL" é um nível de log disparado pela JVM ao encontrar um problema que impede que a aplicação suba.
Ao analisarmos no terminal, o container retornou a mesma informação: "FATAL: database "logs" does not exist". Foi o Postgres que devolveu esse log, isto é, tentaram acessar uma base de dados que não existe no Postgres.
Voltando para o Eclipse, lembra quando analisamos o Docker Compose a pouco tempo atrás? O nome da base de dados era "logsbd". Por isso, vamos à pasta src/main/resources
para abrir a application.properties
e corrigiremos o nome para "logsdb". Salvaremos o arquivo selecionando "Ctrl + S".
application.properties:
//código omitido
spring.datasource.url=jdbc:postgresql://localhost:5432/logsdb
//código omitido
Ao salvarmos, essa aplicação está com o DevTools configurado. Logo, o ideal é ela não subir novamente, visto que a aplicação nem chegou a subir. Mas se tivesse rodando, ela iria recomeçar na hora e conseguiríamos visualizar se está funcional.
Voltaremos para o arquivo CursoApplication.java
e rodaremos a aplicação de novo, selecionando o botão "Run" na parte central da tela. Analisando no console, está aparentemente tudo subindo conforme o esperado. Repare que temos uma linha informando "Started CursoApplication", isso significa que foi startada.
Nesse primeiro contato, já começamos a entender a importância de um log nos informando os eventos que ocorrem na aplicação. Por esse vídeo é isso, no próximo vamos entender melhor essa aplicação e já começaremos a estruturar os logs. Até mais!
Neste vídeo vamos entendermos qual o trabalho de uma API, como ela espera uma requisição e como a consumimos.
Voltando ao Eclipse, essa API está em execução e podemos parar clicando no botão ⏹ no menu na parte superior do console. Depois, selecionaremos o botão com dois "❌" para limpar o console e rodaremos a aplicação novamente pressionando o botão de "Run" com o ícone ▶, na parte superior do Eclipse.
No pacote com o conteúdo da aula 1 há uma collection Alura Logs
, vamos importá-la para o Postman. Dentro dessa collection temos alguns métodos, como POST
, GET
, PUT
e DELETE
. São operações permitidas por essa API.
Essa API realiza o registro dos cursos que serão construídos para a Alura. Do lado esquerdo do Postman, clicaremos na segunda opção GET
, que possui a URI "http://localhost:8080/cursos". Sendo a rota chamada de "cursos" e a aplicação, por estar subindo localmente, "localhost:8080".
Para enviar um GET
, pressionaremos o botão "Send" do lado direito da tela. Perceba que em "Body" é retornado um conteúdo com os campos vazios, foi entregue apenas o conteúdo paginado, já que existe uma paginação configurada. Isso porque não inserimos nenhum registro na base de dados.
Selecionando a primeira opção POST
com a URI "http://localhost:8080/cursos", já temos um registro em "Body" preparado para ser inserido. A API espera um objeto JSON que possua os campos: "numeroMatricula", "numeroCurso", "nomeCurso", "categoriaCurso", "preRequisito", "nomeProfessor" e "periodoCurso". O JPA (Java Persistence API ou, em português "API de persistência Java") que trata da persistência desses campos, a aplicação já está configurada com as regras de negócio.
Registro do
POST
com a URI "http://localhost:8080/cursos":
{
"numeroMatricula": "230419831",
"numeroCurso": "1403198901",
"nomeCurso": "Instrumentação e Refatoração de Logs",
"categoriaCurso": "Site Reliability Engineer",
"preRequisito": "Formação DevOps",
"nomeProfessor": "Kleber Costa",
"periodoCurso": "10 horas"
}
Como membro do time de desenvolvimento dessa API, a nossa função é configurar a parte referente à logs que não foi estruturada.
Faremos a inserção selecionando o botão "Send" do verbo POST
. Note que retornou um "Status: 201 Created", isso significa que o registro foi inserido na base. Se analisarmos em "Body" foi gerado um ID e um novo campo chamado de "dataInscrição", derivado do date do Java que faz esse papel de forma automática quando um registro é inserido na base.
Retorno no Postman do
POST
:
{
"id": "af2287d5-46e0-44e4-8775-edce80febc4e",
"numeroMatricula": "23041983",
"numeroCurso": "1403198901",
"nomeCurso": "Instrumentação e Refatoração de Logs",
"categoriaCurso": "Site Reliability Engineer",
"preRequisito": "Formação DevOps",
"nomeProfessor": "Kleber Costa",
"periodoCurso": "10 horas",
"dataInscrição": "2022-05-25T02:28:49Z"
}
Vamos realizar mais uma inclusão, para isso alteraremos apenas o final dos campos "numeroMatricula" e "numeroCurso" para "02" e modificaremos algumas outras informações:
{
"numeroMatricula": "230419832",
"numeroCurso": "1403198902",
"nomeCurso": "Instrumentação de uma API Spring",
"categoriaCurso": "Site Reliability Engineer",
"preRequisito": "Formação DevOps",
"nomeProfessor": "Kleber Paiva",
"periodoCurso": "12 horas"
}
Vamos clicar no botão "Send" para inserir. Perceba que voltou um "Status: 201 Created", com isso temos dois registros inseridos agora. Se analisarmos o GET
, selecionando a segunda opção do lado esquerdo da tela em "Alura Logs" e, em seguida, clicando no botão "Send". Perceba que é possível visualizarmos o retorno dessas inclusões que acabamos de realizar. Você pode incluir quantos cursos quiser e, inclusive, usar na quarta opção temos um GET
paginado que retorna manipulando a parte de paginação.
Na terceira opção do lado esquerdo da tela temos também o PUT
para realizar um update em um registro. Perceba que já temos alguns dados pré configurados, vamos alterar novamente alguns campos e remover o "dataInscrição":
Verbo
PUT
:
{
"numeroMatricula": "2304198333",
"numeroCurso": "1403198933",
"nomeCurso": "Pilar número um da observabilidade",
"categoriaCurso": "Site Reability Enginner",
"preRequisito": "Formação DevOps",
"nomeProfessor": "Kleber de Paiva Siqueira Costa",
"periodoCurso": "20 horas"
}
Agora, precisamos passar o ID do recurso que queremos atualizar. Voltando para o GET
copiaremos o segundo ID "5d019c2e-7b95-40a0-82d3-cfd0579a3120" e colaremos na rota do verbo PUT
.
URI PUT:
http://localhost:8080/cursos/5d019c2e-7b95-40a0-82d3-cfd0579a3120
Em seguida, clicaremos no botão "Send" do lado direito da tela e, é retornado um "Status: 200 Ok". Isso significa que fizemos um update. Retornando para o verbo GET
selecionaremos o botão "Send" e, note que na resposta é exibido o curso "Pilar número um da observabilidade".
Agora, testaremos a remoção de um registro. Para tal, pegaremos o ID "af2287d5-46e0-44e4-8775-edce80febc4e" em GET
, selecionaremos a penúltima opção do método do lado esquerdo da página, que fica o DELETE
e vamos passar esse ID na rota. Em seguida, clicaremos no botão "Send" do lado direito da tela. Isso nos retorna a mensagem "Curso excluído com sucesso!".
URI DELETE
http://localhost:8080/cursos/af2287d5-46e0-44e4-8775-edce80febc4e
Se formos na aba do GET
e enviarmos novamente, temos o único registro que sobrou como retorno. No POST
clicaremos no botão "Send", para enviar novamente o registro e incluiremos mais um com as seguintes alterações:
POST:
{
"numeroMatricula": "2304198334",
"numeroCurso": "1403198934",
"nomeCurso": "Instrumentação de uma API Spring",
"categoriaCurso": "Site Reability Enginner",
"preRequisito": "Formação DevOps",
"nomeProfessor": "Kleber Costa",
"periodoCurso": "12 horas"
}
Para analisar se conseguimos gerar o mesmo registro duas vezes, vamos clicar duas vezes no botão "Send". O retorno foi a mensagem "O número da matrícula do curso já está em uso", isso significa que existe uma validação de campos.
Agora, isso gerou algum log? É importante entendermos se no Eclipse em CursoApplication
, está sendo gerado alguma camada de log. Não, e esse é o problema que queremos resolver. Precisamos que esses eventos sejam registrados.
No Postman geraremos um caso que retorna um erro. Vamos ao verbo PUT
, na URI temos o ID "5d019c2e-7b95-40a0-82d3-cfd0579a31" que alteraremos o final para "66". Em seguida, clicaremos no botão "Send". Voltou a mensagem "Curso não encontrado!" com um status "404 Not Found", não é um erro mas é uma informação que já deveria ter um evento correspondente.
Na aba do método DELETE
removeremos as letras "c4e" de "af2287d5-46e0-44e4-8775-edce80febc4e", para tentarmos deletar um ID que não existe. Também retornou a mensagem "Curso não encontrado!" com um status "404 Not Found".
Se observarmos a aplicação no Eclipse, vamos perceber que nenhum desses eventos gerou um log. Conduziremos essa aplicação a casos que geram erro 500 também, para validarmos que não há nenhuma informação sendo logada.
Encerramos a aula por aqui. O objetivo deste vídeo é que você possa popularizar a base de dados e conhecer as operações que podemos executar com a API. É importante entendermos que ao fazer uma atualização o que é validade é o número da matrícula e do curso, logo não devem ser iguais. Sempre que um curso é atualizado, é gerado um novo número de matrícula e curso, mas o ID segue sendo o mesmo, sendo imutável
Até o próximo vídeo!
O curso Confiabilidade: garantindo o estado de integridade de sistemas através de logs possui 206 minutos de vídeos, em um total de 45 atividades. Gostou? Conheça nossos outros cursos de Confiabilidade em DevOps, ou leia nossos artigos de DevOps.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.