Alura > Cursos de DevOps > Cursos de Confiabilidade & SRE > Conteúdos de Confiabilidade & SRE > Primeiras aulas do curso Logs e Observabilidade: estratégias de coleta, análise e governança

Logs e Observabilidade: estratégias de coleta, análise e governança

Estratégias de coleta e gestão de logs - Apresentação

Apresentando o treinamento

Olá! Meu nome é Bruno, e vamos iniciar o treinamento sobre estratégias de coleta e gestão de logs (registros).

Neste treinamento, nós vamos abordar o que são os logs (registros) e sua estrutura, os níveis existentes, os tipos de logs (registros) — de servidor e de aplicação —, para que servem os logs (registros) e algumas ferramentas para coleta, centralização e análise ao longo do percurso.

Montando o laboratório e explorando observabilidade

Nesta aula, nós vamos apresentar as introduções, o conceito e a teoria, abordar os tipos de log level (níveis de log) e montar um ambiente de laboratório com VirtualBox. Vamos levantar uma máquina com Windows e outra com Linux atuando como servidores, e ambas irão enviar seus logs para um servidor de logs. Nesse servidor, implementaremos um cluster (agrupamento) do Elasticsearch, composto por Elasticsearch, Logstash e Kibana.

Também faremos testes com Fluent Bit no lugar do Logstash e montaremos um stack (pilha) com Grafana, Loki e Prometheus. Em seguida, veremos OpenTelemetry com Loki e Grafana, com OpenTelemetry substituindo o Prometheus, focando a parte de observabilidade e pensando na coleta de métricas e rastros no futuro. Além disso, analisaremos as três dimensões da observabilidade — métricas, rastros e logs — e como estruturamos essa arquitetura.

Abordando governança de dados e conteúdo extra

Exploraremos a anonimização e a governança de dados, com atenção à LGPD, discutindo como mascarar e anonimizar informações sensíveis dentro dos logs.

Como conteúdo extra ao final, vamos instrumentar logs para Splunk, Datadog, Dynatrace e New Relic. Faremos a exportação dos logs dos nossos servidores para essas ferramentas e analisaremos como cada uma delas interpreta esses registros.

Estratégias de coleta e gestão de logs - Configurando máquina virtual e SSH

Verificando a criação da máquina e realizando configurações iniciais

Vamos verificar se funcionou. A criação da máquina foi concluída, então vamos consultar os logs, analisar o que foi gerado e realizar as configurações iniciais. Vamos sair do slide, abrir a máquina, que já inicializou. O cloud-init aparentemente terminou, portanto não precisamos fazer nenhuma configuração adicional além de configurar o usuário no VirtualBox e a senha. O cloud-init executará todo o processo de configuração da máquina no VirtualBox.

Vamos entrar nela: usuário vboxuser e a senha é 123456. Pronto, estamos autenticados. Vamos abrir o VS Code para trabalhar com mais conforto.

Alternando para root e instalando o servidor ssh

Agora vamos alternar para o usuário root para checar o serviço SSH e, em seguida, instalar o servidor SSH corretamente.

sudo su -

Em seguida, verificamos o status do serviço SSH. Note que ele ainda não está instalado.

systemctl status sshd

Percebemos que o sshd não está instalado. Houve um comando incorreto anteriormente; para evidenciar o erro e a correção, primeiro o comando errado:

apt install sshd

Agora, o comando correto para instalar o servidor SSH:

apt install openssh-server

Concluída a instalação, se executarmos o comando novamente, o SSH já estará em execução.

Ajustando a rede e reinicializando em bridge

Estamos com a rede em NAT. Voltamos a deixar a rede em NAT; provavelmente a alteração para Bridge não foi aplicada porque a máquina estava ligada. O que vamos fazer? Vamos alterar agora. Não mudem no momento da criação: deixemos que a máquina seja criada como NAT por padrão e, depois, vamos desligá-la para ajustar.

Vamos desligar a máquina, abrir o VirtualBox e editar as configurações em Rede para alterar para adaptador em modo Bridge. Também vamos alterar a memória para 1024 MB. Manteremos a CPU com 1 núcleo. Salvamos as alterações e inicializamos novamente. Agora ela deve iniciar com um IP da nossa rede, facilitando o acesso.

Conectando via ssh e acessando os logs iniciais

Após a inicialização, vamos nos autenticar novamente para obter o IP. Para descobrir o endereço, usamos:

ip a

Vemos que a máquina obteve o IP 192.168.1.17. Podemos confirmar na interface.

No terminal do Windows (PowerShell), vamos conectar via SSH:

ssh vboxuser@192.168.1.17

Confirmamos com yes a adição da chave do host e digitamos a senha 123456. Pronto, estamos na máquina, que é o nosso servidor de logs. Vamos alternar para root novamente (123456) e verificar informações iniciais.

sudo su -

Vamos para a pasta "/var/log", que é o diretório padrão de armazenamento de logs no Linux:

cd /var/log/

Aqui dentro, temos diversas informações. Por exemplo, os logs de autenticação em auth.log — são logs de auditoria. Se executarmos:

cat auth.log

veremos registros da sessão SSH que acabamos de abrir (sessão SSH aberta), e, quando a encerrarmos, o fechamento será registrado.

Acompanhando o auth.log em tempo real e observando escalonamento

Abrimos dois terminais para demonstrar em tempo real. No primeiro, acompanhamos o arquivo de autenticação:

tail -f auth.log

No segundo, conectamos novamente via SSH:

ssh vboxuser@192.168.1.17

O arquivo auth.log registra que o usuário vboxuser iniciou outra sessão a partir da origem 192.168.1.4, que é a nossa máquina Windows, e indica que a sessão está aberta. Se encerrarmos essa sessão, o log indicará que a sessão foi finalizada. Isso é fundamental para auditoria: quem se autenticou no sistema, quanto tempo permaneceu autenticado e se houve escalonamento para root.

Vamos fazer isso novamente para observar o escalonamento. Primeiro, estamos como usuário comum, e o log mostra que vboxuser se autenticou no sistema. Agora, se executarmos:

sudo su -

e informarmos a senha novamente, o log registrará que houve uma sessão sudo para o usuário root, originada de vboxuser. Como vboxuser é um usuário com permissões elevadas, o sistema registra quando essas permissões são utilizadas.

Vamos nos deslogar: primeiro saímos de root e, em seguida, encerramos a conexão SSH. Todo esse fluxo ficou registrado no auth.log.

Explorando arquivos de logs em /var/log

Voltando aos demais arquivos em "/var/log", ao executar:

ls -l

vemos outros logs. Em bootstrap.log, ao fazer:

cat bootstrap.log

observamos a parte de inicialização de serviços, como carregamento do initramfs, grep, dpkg e outras aplicações que precisam ser carregadas. Em kern.log (logs do kernel), com:

cat kern.log

vemos os logs do kernel. Em dpkg.log, temos:

cat dpkg.log

que traz o log do gerenciador de pacotes com o que foi configurado, verificado e instalado. Também há os logs do APT na pasta "/var/log/apt", por exemplo:

cat apt/history.log

que contém o histórico do que foi feito via apt.

Verificando o rsyslog e analisando sua configuração

Vamos observar o syslog. Primeiro, verificamos o serviço de logging do sistema:

systemctl status rsyslog

Na primeira tentativa faltou o "s", corrigimos e confirmamos que o rsyslog está instalado. Em seguida, abrimos o arquivo de configuração:

cat /etc/rsyslog.conf

Esse é o arquivo de configuração do rsyslog. Nele, vemos que os logs padrão são direcionados ao syslog. Voltando para "/var/log", podemos visualizar o que está sendo registrado:

cat syslog

Para inspecionar com mais detalhes, vamos abrir o arquivo de configuração com o editor e analisar:

vi /etc/rsyslog.conf

Estamos coletando os logs do sistema localmente; os módulos de recepção por UDP e TCP estão comentados, portanto o modo servidor do rsyslog não está habilitado nem para TCP nem para UDP — apenas logs locais estão sendo processados. Há também a coleta de logs do kernel por meio do módulo correspondente. Nas configurações globais, observamos definições como o formato de arquivo tradicional, a redução de mensagens duplicadas, fileowner definido como syslog, filegroup como adm e filecreatemode como 0644, entre outras.

Utilizando dmesg e journalctl para mensagens do sistema

Agora, vamos ver alguns comandos-chave para mensagens do sistema. O dmesg traz mensagens do kernel:

dmesg

O journalctl também exibe mensagens do sistema:

journalctl

Para acompanhar em tempo real, usamos:

journalctl -f

que é análogo ao tail -f. Para fazer o mesmo com dmesg, utilizamos:

dmesg -w

Se houver dúvidas sobre as opções, podemos consultar a ajuda:

dmesg --help

A opção -w mantém a sessão aberta e os novos registros aparecem à medida que chegam.

Instalando o Docker e preparando o ambiente para o Graylog

Vamos instalar o Docker neste servidor. Primeiro, pesquisamos:

apt search docker

Encontramos as opções, rolamos a lista e vamos instalar docker.io e docker-compose:

apt install docker.io docker-compose

Confirmamos a instalação. Como a máquina está com 1 GB de RAM, provavelmente precisaremos aumentar os recursos para executar o Graylog.

Por fim, vamos utilizar o arquivo que criamos anteriormente com o Gemini.

Vamos utilizar o arquivo criado com a ferramenta de IA Gemini. Nós vamos usá-lo para subir nossa stack (pilha) do Graylog, para verificar na prática como essa configuração funciona e como é eficiente.

É possível entregar uma máquina robusta e colocar em produção o que está no arquivo exatamente como está. Por quê? Porque haverá persistência de dados em disco. Assim, não perderemos esses dados; poderemos acessá-los mesmo que o contêiner encerre e volte a iniciar, pois a informação permanecerá persistida. Nesse cenário, basta realizar alguns ajustes de recursos e garantir que a máquina seja robusta o suficiente para sustentar a carga.

A estrutura ideal é manter as bases de dados em máquinas separadas — neste caso, são duas bases — e não na mesma máquina da aplicação. Entretanto, se a máquina for bastante robusta e o volume de eventos de logs (registros) e de coleta não for grande, não há problema em ter tudo em uma única máquina. Chamamos essa configuração de Always On (sempre ligado).

Lidando com lentidão de rede e examinando registros adicionais

Nossa conexão de internet residencial está um pouco lenta, então pedimos a compreensão de todes. Estamos percebendo que os downloads estão mais lentos do que o normal, pois é necessário baixar cerca de 1 MB e a conexão está impactando esse processo. Enquanto isso, vamos ao outro terminal para examinar alguns registros.

Temos aqui também o dmesg, que traz registros do sistema, especificamente do kernel (núcleo). Temos o journal (diário do sistema). Ao executarmos o comando journalctl, obtemos os registros do sistema. Em "var/log/installer", encontramos registros dos instaladores. Há também registros do Snap, que é o gerenciador de pacotes do Ubuntu, além de registros da instalação do VirtualBox. Existem ainda entradas referentes ao Snap sendo executado como usuário root. O gerenciador de pacotes apt também gera registros. Encontramos os registros de auditoria de autenticação; aqui estão os registros de auditoria que mencionamos, bem como registros de segurança — tanto na parte de auditoria quanto no journalctl, para vermos quais ações foram realizadas no sistema.

Para navegar por esses diretórios e confirmar o que está vazio ou preenchido, executamos alguns comandos:

ls /var/log/
cd /var/log/private/
ls -l
cd ..
cat landscape/sysinfo.log

Em "var/log/private" ainda não há nada. Em "landscape/sysinfo.log" também está vazio. Ao instalar qualquer ferramenta nova, por exemplo, ao instalarmos o Nginx e iniciarmos o serviço, os registros aparecerão em "var/log/nginx". O Apache HTTP Server e o Tomcat possuem diretórios próprios de registros, mas também é possível coletar esses registros e enviá-los para cá. Isso é totalmente configurável, e várias aplicações já utilizam esse caminho por padrão.

Em "etc", temos diversas informações de configuração. O arquivo sysctl.conf é o de parametrização do kernel (núcleo), onde definimos alguns parâmetros de carga. Se quisermos ajustar parâmetros do núcleo, o ideal não é editar diretamente esse arquivo, e sim criar um arquivo de configuração .conf dentro da pasta "sysctl.d" e colocar ali as configurações adicionais do kernel. Dessa forma, adicionamos parâmetros extras (posteriores). Se a intenção for alterar algum valor já existente, tudo bem; mas, para acrescentar novos parâmetros que não estejam configurados, criamos um novo arquivo com esses parâmetros. Para inspecionar:

cat /etc/sysctl.conf
ls /etc/sysctl.d/

O pacote que estamos baixando é pequeno (cerca de 35 MB), mas a conexão está realmente um pouco lenta. Pedimos desculpas; isso já deveria ter finalizado, porém faz parte.

Nós vamos instalar o Docker e iniciar o Docker Compose. Pode ocorrer algum erro devido ao tamanho e aos recursos necessários. A máquina pode travar ou algo similar; se acontecer, vamos acompanhar. Sem problemas.

Apresentando os próximos tópicos das aulas

Na próxima aula, a Aula 2, vamos explorar os registros do Windows. Vamos examinar o Event Viewer (Visualizador de Eventos), ver como visualizar registros a partir do PowerShell, analisar os registros com o NXLog e configurar um exemplo de registro de uma aplicação personalizada. Vamos ver esses pontos antes de, de fato, enviar os registros ao centralizador. Hoje, nosso objetivo é apenas deixar esta máquina pronta. Na Aula 2, veremos mais conceitos de registros no contexto do Windows e do NXLog e, a partir da Aula 3, começaremos a estabelecer a conexão entre máquina cliente e máquina servidora, enviando informações para o Graylog, nosso centralizador. Passaremos a visualizar essas informações na interface do Graylog e a trabalhar com esses dados, incluindo o GELF. Vamos começar a montar dashboards (painéis) simples, mostrando como criá-los, com algumas informações-chave dos registros, para realizarmos buscas. Quem tiver interesse poderá aprofundar-se mais em painéis. Em todas as ferramentas que veremos, há opção de criar dashboards. Vamos importar alguns e trabalhar com alguns, mas o foco será, de fato, a gestão e a administração dos registros.

Voltando ao VirtualBox: esta máquina será utilizada para enviar registros para outra máquina, inicialmente para o Graylog.

Validando o serviço Docker e ajustando permissões de usuário

Concluída a instalação, validamos no terminal: systemctl status docker indica o serviço ativo. Com os comandos abaixo, verificamos serviço, contêineres e imagens:

systemctl status docker
docker ps
docker images

Ao sair do usuário padrão e tentar docker ps, não teremos permissão. Boa prática: em vez de operar como root no laboratório, adicionamos o usuário vboxuser ao grupo docker utilizando usermod. Em seguida, atualizamos as credenciais de grupo na sessão corrente e testamos novamente:

sudo usermod -aG docker vboxuser
newgrp docker
docker ps

Depois disso, docker ps passa a funcionar com o usuário comum. Essa prática é recomendada para que nos acostumemos ao uso adequado de permissões.

Criando o docker-compose do Graylog e subindo a stack

Agora, como usuário comum, criamos a pasta "Graylog" dentro do servidor e acessamos esse diretório. No VS Code, vamos criar o arquivo docker-compose.yml e colar o conteúdo que preparamos (não vamos alterar nada):

mkdir Graylog
cd Graylog/
pwd
vi docker-compose.yml

Conteúdo do docker-compose.yml que define MongoDB, OpenSearch e Graylog, já com variáveis essenciais e volumes persistentes:

version: '3.8'

services:
  # MongoDB: Armazena configurações e metadados
  mongodb:
    image: "mongo:5.0"
    restart: "always"

  # OpenSearch: O motor de busca (sucessor do Elasticsearch)
  opensearch:
    image: "opensearchproject/opensearch:2.4.0"
    environment:
      - "node.name=opensearch"
      - "cluster.name=graylog"
      - "discovery.type=single-node"
      - "bootstrap.memory_lock=true"
      - "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
      - "action.auto_create_index=false"
      - "plugins.security.disabled=true"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    restart: "always"
    volumes:
      - "os_data:/usr/share/opensearch/data"

  # Graylog: A aplicação principal
  graylog:
    image: "graylog/graylog:5.0"
    environment:
      # SENHA DO ADMIN (admin)
      - GRAYLOG_PASSWORD_SECRET=somepasswordpepper1234567890
      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      - GRAYLOG_HTTP_BIND_ADDRESS=0.0.0.0:9000
      - GRAYLOG_HTTP_EXTERNAL_URI=http://192.168.1.17:9000/
      # ENDEREÇO DO ELASTICSEARCH/OPENSEARCH
      - GRAYLOG_ELASTICSEARCH_HOSTS=http://opensearch:9200
      - GRAYLOG_MONGODB_URI=mongodb://mongodb:27017/graylog
    depends_on:
      opensearch:
        condition: "service_started"
      mongodb:
        condition: "service_started"
    ports:
      # Interface Web
      - "9000:9000"
      # Syslog TCP
      - "1514:1514"
      # Syslog UDP
      - "1514:1514/udp"
      # GELF TCP
      - "12201:12201"
      # GELF UDP
      - "12201:12201/udp"
    restart: "always"
    volumes:
      - "graylog_data:/usr/share/graylog/data"

volumes:
  os_data:
  graylog_data:

Para subir a stack em segundo plano (liberando o terminal), executamos:

docker-compose up -d

Se não utilizarmos -d, o terminal ficará bloqueado, pois a execução permanecerá em primeiro plano:

docker-compose up

O docker-compose fará o pull (baixar) das imagens; como sabemos que a conexão está lenta, esse processo pode demorar um pouco.

Encerrando a aula

Vamos encerrar esta aula. Já revisamos o conceito de registros, instalamos o primeiro servidor — o servidor de registros — e criamos o docker-compose que vai compor o Graylog com o MongoDB e o OpenSearch, que é uma alternativa ao Elasticsearch, utilizando a mesma engine (mecanismo), apenas com mudança de nome. Vamos utilizar essa estrutura a partir da Aula 3. Na prática da Aula 3, passaremos a usar a estrutura do Graylog no dia a dia e a ajustá-la ao longo das aulas.

Obrigado, pessoal. Até a próxima aula.

Estratégias de coleta e gestão de logs - Configurando o ambiente de virtualização

Iniciando a criação do ambiente

Vamos iniciar a criação do nosso ambiente. Nós o desenvolveremos conforme o avanço das aulas e, ao final, teremos todo o ambiente pronto. Não executaremos as duas ferramentas ao mesmo tempo. Primeiro, testaremos o Graylog para observar seu funcionamento. Em seguida, trabalharemos com a stack (pilha) ELK e, depois, com a stack (pilha) do Grafana, utilizando o Loki e o Alloy.

Uma informação importante: o Promtail foi descontinuado em 26 de março. O Promtail era a ferramenta responsável por enviar dados ao Loki. O Loki armazena esses logs e os exibe no painel do Grafana (dashboard — painel). Vamos conhecer a nova ferramenta que realiza esse envio ao Loki.

Primeiro, vamos criar o servidor LogServer. Quanto à rede, vamos ignorar a configuração visível agora, pois será utilizado outro endereço IP, o da nossa rede atual. Os recursos também serão ajustados para menos, já que se trata apenas de um laboratório: não será necessário utilizar 4 GB de RAM; utilizaremos menos memória.

Instalando o VirtualBox e baixando o Ubuntu

Agora, vamos baixar o Ubuntu 22 e realizar a instalação. Sairemos do slide para acessar a página do VirtualBox: virtualbox.org/wiki/Downloads. Também é possível pesquisar no Google por “download (baixar) VirtualBox” para chegar a essa página. Vamos baixar para Windows, pois estamos utilizando Windows no momento. Abriremos o instalador. Com o instalador aberto, avançaremos, aceitaremos os termos de licença e seguiremos sem alterar as opções padrão. Confirmaremos com “Yes”. Marcaremos a opção de adicionar ao Menu Iniciar. Não criaremos um ícone na Área de Trabalho, pois preferimos mantê-la sem ícones. Manteremos a opção de iniciar por padrão quando um arquivo .ovf for aberto, o que é interessante quando baixarmos uma imagem pronta no formato reconhecido pelo VirtualBox, pois a configuração da máquina virtual será iniciada automaticamente. No nosso caso, utilizaremos uma imagem .iso comum, então seguiremos com a instalação.

Enquanto a instalação ocorre, podemos já pesquisar no Google por “download (baixar) Ubuntu Server 22.04”. Essa será a versão que testaremos. É uma LTS com cinco anos de suporte, válida até 2027. Vamos baixar a 22.04. Em “Alternative Downloads” e “Previous Release”, é possível acessar a 22.04 LTS. Iniciaremos o download (baixa). O arquivo tem aproximadamente 2 GB, e o download (baixa) não deve demorar muito, cerca de 5 minutos.

Enquanto isso, voltaremos ao VirtualBox e concluiremos a instalação. O VirtualBox será iniciado para analisarmos seus recursos. Faremos uma visão geral de como funciona essa ferramenta de virtualização de sistemas operacionais e de máquinas.

Explorando as opções do VirtualBox

Na tela inicial, ao clicar em “Novo”, criaremos uma nova máquina virtual. Informaremos o nome da VM e selecionaremos o diretório onde a máquina virtual será criada (o arquivo correspondente à VM). Depois, poderemos abrir esse diretório para verificar como os arquivos ficam organizados. Selecionaremos a imagem que estamos baixando (uma imagem .iso; reparem na extensão .iso). Assim que o download (baixa) terminar, poderemos selecioná-la. Escolheremos o tipo do sistema: Linux, distribuição Ubuntu, para que o VirtualBox identifique corretamente os modos de instalação da imagem. Uma imagem .iso é um pacote com arquivos de instalação.

Podemos continuar, mas como nenhuma imagem .iso foi selecionada ainda, vamos cancelar para ver outras opções. Em “Abrir”, selecionaríamos um arquivo .ovf ou .ova, isto é, uma imagem já pronta em formato de virtualizador. Em “Preferências”, podemos configurar o ambiente de virtualização: alterar o idioma, ajustar configurações de exibição e modificar o diretório padrão de armazenamento das VMs. Vamos verificar rapidamente o armazenamento: temos cerca de 57 GB livres, então manteremos esse diretório. Há configurações avançadas de entrada, incluindo a possibilidade de habilitar USB nos dispositivos de conexão (mostraremos isso mais adiante). Também podemos importar e exportar: ao abrir um arquivo, selecionamos o tipo de arquivo aceito para importação direta; após a criação de uma VM, podemos exportá-la, gerando um arquivo em formato de virtualizador para utilizá-lo em outros locais, em outros virtualizadores ou em outras máquinas. Assim, a VM sai pronta para simplesmente ligarmos e utilizarmos em outros hipervisores (hypervisors — hipervisores).

Na seção de extensões, instalaremos os pacotes necessários. Será preciso baixar as extensões para habilitar reconhecimento de controladores (drivers — controladores) e outros recursos. Em “Mídias”, podemos carregar a partir de um meio e simular um dispositivo. Por exemplo, se tivermos uma imagem .iso e quisermos montá-la, adicionaremos a mídia e a montaremos como se fosse um leitor de disco (CD/DVD) ou uma unidade USB. Essa mídia ficará armazenada e poderá ser anexada a qualquer sistema operacional convidado, permitindo que a máquina virtual leia esse conteúdo.

Configurando redes e avaliando recursos

Na parte de rede, ao instalar o VirtualBox na máquina, ele cria uma interface de rede e define um IP virtual. Essa interface não está vinculada a nenhuma interface física. Se abrirmos o PowerShell e executarmos o comando ipconfig, veremos a rede física (a placa Wi‑Fi da máquina), que possui o endereçamento IP da rede residencial, além das redes virtualizadas: a do WSL do próprio Windows e o adaptador do VirtualBox, que cria a rede virtual. Reconhecemos essa rede pelo intervalo exibido na própria interface do VirtualBox. Podemos criar outras interfaces, como uma HostOnlyNetworkInterface, que criará uma nova interface de rede. Ao criar, passamos a ter, por exemplo, as redes 192.168.5.1 e 192.168.59.1. É possível ver as propriedades de cada uma, realizar alterações, configurar o adaptador automaticamente ou manualmente, conforme a necessidade de conexão com recursos externos.

Para verificar isso no Windows, execute o comando a seguir no PowerShell:

ipconfig

Esse comando lista as interfaces físicas e virtuais, incluindo a criada pelo VirtualBox, permitindo validar endereços IP e faixas de rede utilizadas.

Em “Recursos”, observamos a utilização atual do sistema operacional em termos de CPU, memória e discos, lembrando que a VM compartilha os recursos com o sistema operacional da máquina física; ela não adiciona novos recursos, apenas utiliza os já disponíveis.

Criando a máquina virtual LogServer

Com o download (baixa) concluído, clicaremos em “Novo”. Definiremos o nome da máquina, por exemplo, “log server”. A VM ficará no diretório já configurado. Agora, selecionaremos a imagem .iso na pasta “Downloads” — o VirtualBox já a reconhece pelo formato. Em “OS edition”, manteremos Linux; o VirtualBox identificou Ubuntu para nós (exibiu 22.10 neste caso, embora tenhamos baixado a 22.04; isso não é relevante agora). Prosseguiremos. Se o assistente reclamar do nome, pode aparecer a mensagem “Hostname must be at least two alphanumeric characters”. Ajustaremos o nome para atender a essa exigência, removendo caracteres inválidos e deixando um nome válido para a máquina virtual.

Definiremos credenciais: usuário “virtualbox user” e senha “123456”, confirmando a senha. Essa será a senha do sistema operacional convidado. Finalizaremos a criação. Ao concluir, a VM será iniciada e a instalação da imagem .iso começará. Aguardaremos o término. Enquanto isso, já podemos observar como ficou a configuração: memória principal em 2 GB, algo que pode ser alterado (mais adiante mostraremos onde fazer isso). A máquina está inicializando para realizar a instalação. Depois, reduziremos esses recursos, pois não é necessário tanto neste momento.

Para quem estiver criando agora e desejar ajustar os recursos, é possível desligar a VM, acessar “Configurações” e, em “Sistema”, alterar a quantidade de memória e CPU. A VM precisa estar desligada para permitir a edição desses recursos. Podemos, por exemplo, reduzir para 1 CPU e 1 GB de RAM inicialmente. Neste momento, deixaremos a inicialização concluir. A partir daqui, seguiremos o processo de instalação de um sistema operacional desde o início.

Inicializando o Ubuntu Server e ajustando a rede

Não se trata de uma OVA ou OVF já configurada. Vamos realizar a configuração do zero. Inicializaremos o Ubuntu Server 22.04. No nosso ambiente, o sistema já inicia diretamente. Vamos acessar com o usuário VBox User e a senha 123456, que configuramos. O Cloud-Init está executando toda a etapa de inicialização do sistema operacional.

Esta é a interface de rede da máquina virtual: enp0s3. Quando a inicialização terminar, vamos desligar a máquina virtual, abrir as configurações, reduzir a memória (como planejado) e configurar a rede. Em Rede, vamos alterar de NAT para Bridge (modo ponte). Colocaremos a placa em modo Bridge para que a máquina virtual suba na mesma rede da nossa residência, obtenha um endereço IP via a mesma infraestrutura de rede do computador hospedeiro e permita comunicação direta, sem necessidade de túneis. O NAT cria um túnel e faz um arranjo para que nos conectemos à máquina; em Bridge, não. Em modo ponte, conectamo-nos diretamente à máquina virtual, sem esses subterfúgios, operando diretamente na camada 2, pois estamos na mesma rede da máquina virtual.

Aplicaremos o modo Bridge e confirmaremos com OK, já que o sistema permitiu. A memória ainda não pode ser ajustada neste momento, então manteremos como está. Observamos que a interface é Wi‑Fi; se houver mais de uma, devemos selecionar a interface adequada. Confirmaremos com OK.

Na tela inicial, ainda não é exibida a informação de IP. Não há expansão dessa área na interface. Obteremos o endereço IP assim que a máquina estiver disponível para acesso. O Cloud-Init continua em execução.

Observando os recursos da VM

Na interface, na parte inferior, conseguimos ver todos os recursos dessa máquina virtual:

Veremos todos esses itens em breve, quando a inicialização terminar. Faremos os ajustes necessários. Enquanto isso, vamos adiantar a preparação do ambiente.

Introduzindo o uso de IA no laboratório

Ao final do treinamento, teremos algumas aulas específicas sobre como utilizar a IA para nos apoiar no depurador de problemas, analisando logs e na tomada de decisões. Para que já nos acostumemos a solicitar informações à IA, especialmente no que diz respeito à criação de arquivos para nós — algo que poderíamos fazer manualmente, mas não é necessário — abriremos qualquer IA disponível. Pode ser o ChatGPT ou o Gemini. Neste caso, abriremos o Gemini.

No Gemini, informaremos o seguinte: estamos levantando um Ubuntu Server 22.04 e queremos subir o Graylog. Primeiro, vamos mostrar os logs gerados na parte de SSH e na parte de auditoria de segurança; depois, instalaremos o Docker, subiremos o Graylog e começaremos a levantar outras máquinas para enviar os logs ao Graylog. Esse será nosso primeiro laboratório.

Como exemplo prático, queremos subir o Graylog e precisamos de um Docker Compose completo, com persistência de dados e autenticação configurada. Ao enviar essa solicitação, a IA entende que vamos levantar um servidor Graylog em Docker, pois indicamos que queremos um arquivo de Docker Compose. A IA retorna as informações necessárias e propõe a estrutura do Docker Compose.

Detalhando a proposta de Docker Compose

A proposta inclui a seção services:

Vamos materializar essa proposta no arquivo docker-compose.yml, adicionando os serviços de forma progressiva. Começamos pela base de dados do Graylog, o MongoDB, já declarando a versão do Compose conforme retornado pela IA e a seção de serviços:

version: "3.8"

services:
  # MongoDB: Armazena configurações e metadados
  mongodb:
    image: "mongo:5.0"
    volumes:
      - "mongodb_data:/data/db"
    restart: "always"

Esse bloco define o serviço do MongoDB, com volume persistente mapeado para /data/db e política de reinício para garantir disponibilidade.

Adicionando o OpenSearch ao Compose

Em seguida, adicionamos o OpenSearch, que fará a indexação:

  # OpenSearch: O motor de busca (sucessor do Elasticsearch)
  opensearch:
    image: "opensearchproject/opensearch:2.4.0"
    environment:
      - "node.name=opensearch"
      - "cluster.name=graylog"
      - "discovery.type=single-node"
      - "bootstrap.memory_lock=true"
      - "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
      - "action.auto_create_index=false"
      - "plugins.security.ssl.http.enabled=false"
      - "plugins.security.disabled=true"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - "os_data:/usr/share/opensearch/data"
    restart: "always"

Note que configuramos o OpenSearch em modo single-node, ajustamos limites de memória/arquivos e mapeamos um volume para os dados de índice.

Configurando o serviço Graylog no Compose

Por fim, adicionamos o serviço principal do Graylog, com dependências explícitas, entrypoint aguardando o OpenSearch e variáveis de ambiente essenciais, além das portas de entrada para os protocolos mais comuns:

  # Graylog: A aplicação principal
  graylog:
    image: "graylog/graylog:5.0"
    depends_on:
      mongodb:
        condition: "service_started"
      opensearch:
        condition: "service_started"
    entrypoint: /usr/bin/tini -- wait-for-it opensearch:9200 --  /docker-entrypoint.sh
    environment:
      # Senha do usuário admin (admin)
      # IMPORTANTE: Altere este valor para um hash SHA-256 da sua senha
      - "GRAYLOG_PASSWORD_SECRET=somepasswordpepper"
      - "GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"
      - "GRAYLOG_HTTP_BIND_ADDRESS=0.0.0.0:9000"
      - "GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9000/"
      - "GRAYLOG_ELASTICSEARCH_HOSTS=http://opensearch:9200"
    ports:
      # Porta para a interface web
      - "9000:9000"
      # Portas para receber logs
      - "1514:1514"   # Syslog TCP
      - "1514:1514/udp" # Syslog UDP
      - "12201:12201" # GELF TCP
      - "12201:12201/udp" # GELF UDP
    volumes:
      - "graylog_data:/usr/share/graylog/data"
    restart: "always"

Para concluir, declaramos os volumes persistentes na raiz do arquivo:

volumes:
  mongodb_data:
  os_data:
  graylog_data:

Existe ainda um volume do Graylog para persistência de dados e a política de reinício restart: always, garantindo que o serviço seja religado automaticamente em caso de falhas ou quando o ambiente for derrubado e levantado novamente. Observamos que a chave version no Docker Compose moderno está deprecada e não precisa mais ser especificada no arquivo. Se a IA trouxer essa linha (como no nosso exemplo), você pode mantê-la ou removê-la — o Compose atual funciona sem ela.

Preparando o VS Code e organizando arquivos

Não vamos copiar o arquivo agora. Voltaremos à nossa máquina virtual. Ela ainda está subindo; está demorando um pouco. Enquanto isso, trabalharemos com o Visual Studio Code. Se ainda não o tiverem, façam o download do VS Code no seu sistema operacional. Pesquisando por “Download VS Code” no Google, a primeira opção é a válida. Baixem conforme o sistema operacional. O VS Code integra-se ao Copilot; se quisermos usar uma IA, podemos configurá-la e autenticar no GitHub. Neste momento, não vamos autenticar no GitHub. Usaremos uma IA no navegador apenas para criar os arquivos, entendê-los e aplicar efetivamente as configurações. Depois, começaremos a interagir com a IA nas aulas finais, avaliando os logs e executando essas análises.

Verifiquemos o andamento da instalação: ainda está instalando o kernel e concluindo a inicialização da máquina; ao final, o sistema ficará pronto. O processo está um pouco lento, provavelmente por haver poucos recursos disponíveis.

No VS Code, vamos clicar na opção do Explorador de Arquivos (Explorer), abrir um diretório, navegar até a pasta "Documentos" e criar a pasta "greylog". Em seguida, abriremos a pasta "greylog" no VS Code. Agora já podemos criar o primeiro arquivo: clicaremos em novo arquivo e escreveremos docker-compose.yml. Esse primeiro arquivo YAML será o que acabamos de gerar com a ajuda da IA. Voltaremos ao VS Code e colaremos o conteúdo indicado pela IA. Por ora, não faremos alterações. Se quisermos expor outras portas, adicionaremos na seção apropriada; há várias que podemos expor e veremos isso adiante. Salvaremos o arquivo.

Inserindo o docker-compose completo e revisando o plano

Conteúdo completo do docker-compose.yml, conforme a IA sugeriu:

version: "3.8"

services:
  # MongoDB: Armazena configurações e metadados
  mongodb:
    image: "mongo:5.0"
    volumes:
      - "mongodb_data:/data/db"
    restart: "always"

  # OpenSearch: O motor de busca (sucessor do Elasticsearch)
  opensearch:
    image: "opensearchproject/opensearch:2.4.0"
    environment:
      - "node.name=opensearch"
      - "cluster.name=graylog"
      - "discovery.type=single-node"
      - "bootstrap.memory_lock=true"
      - "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
      - "action.auto_create_index=false"
      - "plugins.security.ssl.http.enabled=false"
      - "plugins.security.disabled=true"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65536
        hard: 65536
    volumes:
      - "os_data:/usr/share/opensearch/data"
    restart: "always"

  # Graylog: A aplicação principal
  graylog:
    image: "graylog/graylog:5.0"
    depends_on:
      mongodb:
        condition: "service_started"
      opensearch:
        condition: "service_started"
    entrypoint: /usr/bin/tini -- wait-for-it opensearch:9200 --  /docker-entrypoint.sh
    environment:
      # Senha do usuário admin (admin)
      # IMPORTANTE: Altere este valor para um hash SHA-256 da sua senha
      - "GRAYLOG_PASSWORD_SECRET=somepasswordpepper"
      - "GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"
      - "GRAYLOG_HTTP_BIND_ADDRESS=0.0.0.0:9000"
      - "GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9000/"
      - "GRAYLOG_ELASTICSEARCH_HOSTS=http://opensearch:9200"
    ports:
      # Porta para a interface web
      - "9000:9000"
      # Portas para receber logs
      - "1514:1514"   # Syslog TCP
      - "1514:1514/udp" # Syslog UDP
      - "12201:12201" # GELF TCP
      - "12201:12201/udp" # GELF UDP
    volumes:
      - "graylog_data:/usr/share/graylog/data"
    restart: "always"

volumes:
  mongodb_data:
  os_data:
  graylog_data:

Vamos conferir como está a criação da máquina: ainda está concluindo algumas configurações. Retomando rapidamente o plano: estamos montando agora o servidor LogServer e veremos seus logs em seguida. O acesso será por SSH por meio da rede em modo ponte. Analisaremos os logs de auditoria, de segurança e do kernel. A partir da próxima aula, montaremos o Graylog de fato e os servidores de aplicação que enviarão logs ao Graylog. Hoje revisaremos o conceito de log que vimos na primeira aula, observando essas informações dentro de um servidor.

Sobre o curso Logs e Observabilidade: estratégias de coleta, análise e governança

O curso Logs e Observabilidade: estratégias de coleta, análise e governança possui 369 minutos de vídeos, em um total de 61 atividades. Gostou? Conheça nossos outros cursos de Confiabilidade & SRE 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:

Aprenda Confiabilidade & SRE acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas