DevOps & CI/CD

O que Todo Dev Deve Saber sobre ELK Stack: Elasticsearch, Logstash e Kibana para Logs Centralizados

15 min de leitura

O que Todo Dev Deve Saber sobre ELK Stack: Elasticsearch, Logstash e Kibana para Logs Centralizados

Introdução ao ELK Stack O ELK Stack é uma solução de código aberto composta por três componentes principais: Elasticsearch, Logstash e Kibana. Juntos, formam uma plataforma poderosa para coleta, processamento, armazenamento e visualização de logs em tempo real. Se você trabalha com sistemas distribuídos, microsserviços ou qualquer aplicação que gere grandes volumes de dados de log, entender o ELK Stack é fundamental para diagnosticar problemas rapidamente e manter a saúde da sua infraestrutura. A razão pela qual o ELK Stack se tornou padrão da indústria é simples: sem uma solução centralizada de logs, você estaria conectando em múltiplos servidores, usando ferramentas diferentes e perdendo horas procurando por um erro que ocorreu há dias. O Elasticsearch resolve isso indexando logs de forma rápida e escalável, o Logstash processa e normaliza esses dados, e o Kibana oferece uma interface visual intuitiva para exploração e análise. Compreendendo os Componentes Fundamentais Elasticsearch: O Mecanismo de Busca e Armazenamento O Elasticsearch é um mecanmotor de

<h2>Introdução ao ELK Stack</h2>

<p>O ELK Stack é uma solução de código aberto composta por três componentes principais: Elasticsearch, Logstash e Kibana. Juntos, formam uma plataforma poderosa para coleta, processamento, armazenamento e visualização de logs em tempo real. Se você trabalha com sistemas distribuídos, microsserviços ou qualquer aplicação que gere grandes volumes de dados de log, entender o ELK Stack é fundamental para diagnosticar problemas rapidamente e manter a saúde da sua infraestrutura.</p>

<p>A razão pela qual o ELK Stack se tornou padrão da indústria é simples: sem uma solução centralizada de logs, você estaria conectando em múltiplos servidores, usando ferramentas diferentes e perdendo horas procurando por um erro que ocorreu há dias. O Elasticsearch resolve isso indexando logs de forma rápida e escalável, o Logstash processa e normaliza esses dados, e o Kibana oferece uma interface visual intuitiva para exploração e análise.</p>

<h2>Compreendendo os Componentes Fundamentais</h2>

<h3>Elasticsearch: O Mecanismo de Busca e Armazenamento</h3>

<p>O Elasticsearch é um mecanmotor de busca distribuído construído sobre o Apache Lucene. Funciona como um banco de dados NoSQL otimizado para buscas em tempo real e análises. Cada documento armazenado no Elasticsearch é indexado — isso significa que seus campos são analisados e organizados em estruturas que permitem buscas extremamente rápidas, mesmo em bilhões de registros. Você não faz buscas sequenciais como em um banco de dados relacional tradicional; o Elasticsearch usa índices invertidos que mapeiam termos para os documentos que os contêm.</p>

<p>A unidade fundamental no Elasticsearch é o <strong>índice</strong>. Um índice é similar a uma tabela em um banco de dados relacional, mas muito mais flexível. Dentro de um índice, você tem <strong>documentos</strong> (registros JSON) e <strong>tipos</strong> (em versões mais antigas; versões recentes usam apenas um tipo por índice). Documentos são armazenados em <strong>shards</strong> (partições) que podem ser distribuídos entre múltiplos nós (servidores), permitindo escalabilidade horizontal.</p>

<pre><code class="language-json">{

&quot;took&quot;: 5,

&quot;timed_out&quot;: false,

&quot;_shards&quot;: {

&quot;total&quot;: 5,

&quot;successful&quot;: 5,

&quot;skipped&quot;: 0,

&quot;failed&quot;: 0

},

&quot;hits&quot;: {

&quot;total&quot;: {

&quot;value&quot;: 1,

&quot;relation&quot;: &quot;eq&quot;

},

&quot;max_score&quot;: 1.0,

&quot;hits&quot;: [

{

&quot;_index&quot;: &quot;logs-2024-01-15&quot;,

&quot;_type&quot;: &quot;_doc&quot;,

&quot;_id&quot;: &quot;1&quot;,

&quot;_score&quot;: 1.0,

&quot;_source&quot;: {

&quot;timestamp&quot;: &quot;2024-01-15T10:30:45Z&quot;,

&quot;level&quot;: &quot;ERROR&quot;,

&quot;message&quot;: &quot;Connection timeout&quot;,

&quot;service&quot;: &quot;payment-api&quot;,

&quot;host&quot;: &quot;server-01&quot;

}

}

]

}

}</code></pre>

<h3>Logstash: Processamento e Transformação de Dados</h3>

<p>O Logstash é um pipeline de processamento de dados que extrai, transforma e enriquece logs antes de serem armazenados. Ele funciona em três etapas: <strong>input</strong> (coleta de dados), <strong>filter</strong> (transformação e enriquecimento) e <strong>output</strong> (envio para Elasticsearch ou outro destino). A maior parte do poder do Logstash está nos filters, onde você pode fazer parse de dados não estruturados, adicionar campos calculados, descartar informações desnecessárias ou correlacionar dados de múltiplas fontes.</p>

<p>Uma configuração típica do Logstash começa recebendo logs de um arquivo, socket, API ou qualquer outra fonte, depois aplica padrões regex ou plugins específicos para extrair estrutura, e finalmente envia para o Elasticsearch com campos bem definidos. Isso torna seus logs pesquisáveis e analisáveis de forma eficiente, em vez de serem apenas strings brutas.</p>

<pre><code class="language-logstash">input {

file {

path =&gt; &quot;/var/log/application/*.log&quot;

start_position =&gt; &quot;beginning&quot;

codec =&gt; multiline {

pattern =&gt; &quot;^\[&quot;

negate =&gt; true

what =&gt; &quot;previous&quot;

}

}

}

filter {

grok {

match =&gt; {

&quot;message&quot; =&gt; &quot;\[%{TIMESTAMP_ISO8601:timestamp}\] %{LOGLEVEL:level} \[%{DATA:service}\] %{GREEDYDATA:message}&quot;

}

}

date {

match =&gt; [ &quot;timestamp&quot;, &quot;ISO8601&quot; ]

target =&gt; &quot;@timestamp&quot;

}

if [level] == &quot;ERROR&quot; {

mutate {

add_field =&gt; { &quot;alert&quot; =&gt; true }

}

}

}

output {

elasticsearch {

hosts =&gt; [&quot;localhost:9200&quot;]

index =&gt; &quot;logs-%{+YYYY.MM.dd}&quot;

}

}</code></pre>

<p>Neste exemplo, o Logstash lê logs de arquivos, usa o filtro <strong>grok</strong> (que é uma linguagem de pattern matching) para extrair campos estruturados, converte o timestamp para o formato padrão do Elasticsearch, adiciona um campo de alerta para erros, e envia tudo para o Elasticsearch em índices diários.</p>

<h3>Kibana: Visualização e Exploração Interativa</h3>

<p>O Kibana é a interface visual do ELK Stack. Ele permite que você crie dashboards, execute buscas complexas no Elasticsearch, explore dados em tempo real e configure alertas. A força do Kibana não está apenas em exibir dados bonitos — está em permitir que você faça perguntas ao seu sistema de logs rapidamente, sem escrever código.</p>

<p>Em Kibana, você trabalha com <strong>índices</strong>, <strong>visualizações</strong> e <strong>dashboards</strong>. Um índice é o padrão de índices do Elasticsearch que você quer analisar (por exemplo, <code>logs-*</code> para todos os índices que começam com &quot;logs&quot;). Uma visualização é uma representação gráfica de uma query (gráfico de barras, linhas, tabelas, maps, etc.). Um dashboard é uma coleção de visualizações que conta uma história sobre sua infraestrutura.</p>

<h2>Arquitetura Prática e Padrões de Implementação</h2>

<h3>Topologia de Produção Recomendada</h3>

<p>Em ambientes de produção, o ELK Stack raramente é instalado em um único servidor. A topologia típica envolve múltiplos nós de Elasticsearch para alta disponibilidade, múltiplas instâncias de Logstash para processamento paralelo e escalável, e pelo menos uma instância de Kibana para visualização. Você também pode adicionar um <strong>Filebeat</strong> (agente leve) em cada servidor da sua aplicação para coletar logs de forma eficiente, ao invés de usar o Logstash diretamente para leitura de arquivos.</p>

<p>A razão para separar componentes é garantir que um deles fique indisponível sem derrubar todo o sistema. Se o Kibana cair, você ainda consegue enviar logs. Se um nó Elasticsearch sair, outros replicam os dados. Se o Logstash ficar congestionado, as mensagens ficam em fila até ele processar — o importante é não perder logs.</p>

<pre><code class="language-yaml"># Exemplo de topologia com Docker Compose

version: &#039;3.8&#039;

services:

elasticsearch:

image: docker.elastic.co/elasticsearch/elasticsearch:8.0.0

environment:

  • discovery.type=single-node
  • xpack.security.enabled=false

ports:

  • &quot;9200:9200&quot;

volumes:

  • es_data:/usr/share/elasticsearch/data

logstash:

image: docker.elastic.co/logstash/logstash:8.0.0

volumes:

  • ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf

ports:

  • &quot;5000:5000&quot;

depends_on:

  • elasticsearch

kibana:

image: docker.elastic.co/kibana/kibana:8.0.0

ports:

  • &quot;5601:5601&quot;

environment:

  • ELASTICSEARCH_HOSTS=http://elasticsearch:9200

depends_on:

  • elasticsearch

volumes:

es_data:</code></pre>

<h3>Filtragem e Enriquecimento Avançado</h3>

<p>A verdadeira potência do Logstash surge quando você começa a enriquecer logs com contexto externo. Imagine que seus servidores web geram logs com endereços IP de clientes — você pode usar o filtro <strong>geoip</strong> para adicionar localização geográfica, ou o filtro <strong>translate</strong> para mapear códigos de erro para mensagens legíveis. Você também pode usar expressões condicionais para aplicar diferentes transformações dependendo do tipo de log.</p>

<pre><code class="language-logstash">filter {

Extrair informações do log

grok {

match =&gt; {

&quot;message&quot; =&gt; &quot;%{IP:client_ip} - %{DATA:user} \[%{HTTPDATE:timestamp}\] \&quot;%{WORD:method} %{DATA:request} HTTP/%{NUMBER:http_version}\&quot; %{NUMBER:status_code} %{NUMBER:bytes}&quot;

}

}

Adicionar geolocalização

geoip {

source =&gt; &quot;client_ip&quot;

target =&gt; &quot;geoip&quot;

}

Traduzir códigos de status HTTP

translate {

field =&gt; &quot;status_code&quot;

destination =&gt; &quot;status_description&quot;

dictionary =&gt; {

&quot;200&quot; =&gt; &quot;OK&quot;

&quot;404&quot; =&gt; &quot;Not Found&quot;

&quot;500&quot; =&gt; &quot;Internal Server Error&quot;

}

}

Remover logs de healthcheck (ruído)

if [request] =~ /\/health/ {

drop { }

}

Marcar requisições lentas

if [response_time] &gt; 1000 {

mutate {

add_tag =&gt; [ &quot;slow_request&quot; ]

}

}

}</code></pre>

<h2>Casos de Uso Reais e Melhores Práticas</h2>

<h3>Correlação de Eventos Distribuídos</h3>

<p>Um dos maiores desafios em sistemas distribuídos é rastrear uma requisição através de múltiplos serviços. Se uma requisição falha em sua API, ela pode ter passado pela API gateway, serviço de autenticação, banco de dados e cache — você precisa encontrar o log exato em cada um desses serviços. A solução é usar um <strong>correlation ID</strong> ou <strong>trace ID</strong> que acompanha a requisição por toda sua jornada.</p>

<p>Seu código deve gerar um identificador único quando a requisição entra no sistema e incluir esse ID em cada log subsequente. Quando você procura por esse ID no Kibana, todos os logs relacionados àquela requisição aparecem juntos, permitindo você acompanhar exatamente onde o problema ocorreu.</p>

<pre><code class="language-python">import uuid

import logging

from elasticsearch import Elasticsearch

from pythonjsonlogger import jsonlogger

Configurar logging estruturado com trace ID

class TraceIDFilter(logging.Filter):

def filter(self, record):

record.trace_id = getattr(record, &#039;trace_id&#039;, str(uuid.uuid4()))

return True

logger = logging.getLogger(__name__)

handler = logging.StreamHandler()

formatter = jsonlogger.JsonFormatter(&#039;%(timestamp)s %(level)s %(trace_id)s %(message)s&#039;)

handler.setFormatter(formatter)

logger.addHandler(handler)

logger.addFilter(TraceIDFilter())

Uso em aplicação Flask

from flask import Flask, request, g

app = Flask(__name__)

@app.before_request

def set_trace_id():

g.trace_id = request.headers.get(&#039;X-Trace-ID&#039;, str(uuid.uuid4()))

@app.route(&#039;/api/users/&lt;user_id&gt;&#039;)

def get_user(user_id):

extra = {&#039;trace_id&#039;: g.trace_id}

logger.info(f&quot;Fetching user {user_id}&quot;, extra=extra)

Passar trace ID para serviços downstream

headers = {&#039;X-Trace-ID&#039;: g.trace_id}

... fazer chamadas HTTP com headers

return {&quot;user_id&quot;: user_id}</code></pre>

<h3>Configuração de Índices Inteligente</h3>

<p>Uma prática fundamental em produção é usar <strong>índices por tempo</strong> (diários, semanais). Isso permite que você mantenha dados recentes no armazenamento rápido e arquive ou delete dados antigos sem afetar o desempenho. O Elasticsearch tem uma feature chamada <strong>Index Lifecycle Management (ILM)</strong> que automatiza essa rotação de índices, aplicando políticas como: mover índices para armazenamento mais lento após 30 dias, deletar após 90 dias, ou fazer rollover quando atingem um tamanho específico.</p>

<pre><code class="language-json">{

&quot;policy&quot;: &quot;logs-policy&quot;,

&quot;phases&quot;: {

&quot;hot&quot;: {

&quot;min_age&quot;: &quot;0d&quot;,

&quot;actions&quot;: {

&quot;rollover&quot;: {

&quot;max_primary_shard_size&quot;: &quot;50gb&quot;,

&quot;max_age&quot;: &quot;1d&quot;

},

&quot;set_priority&quot;: {

&quot;priority&quot;: 100

}

}

},

&quot;warm&quot;: {

&quot;min_age&quot;: &quot;30d&quot;,

&quot;actions&quot;: {

&quot;set_priority&quot;: {

&quot;priority&quot;: 50

},

&quot;shrink&quot;: {

&quot;number_of_shards&quot;: 1

}

}

},

&quot;cold&quot;: {

&quot;min_age&quot;: &quot;90d&quot;,

&quot;actions&quot;: {

&quot;set_priority&quot;: {

&quot;priority&quot;: 0

}

}

},

&quot;delete&quot;: {

&quot;min_age&quot;: &quot;365d&quot;,

&quot;actions&quot;: {

&quot;delete&quot;: {}

}

}

}

}</code></pre>

<h3>Segurança e Acesso Controlado</h3>

<p>Em produção, você não quer que qualquer pessoa acesse seus logs — eles contêm informações sensíveis como tokens, senhas e dados pessoais. O Elasticsearch X-Pack (agora integrado nas versões mais recentes) oferece autenticação baseada em usuário, criptografia em trânsito (TLS/SSL) e controle granular de acesso (Role-Based Access Control — RBAC). O Kibana respeita esses controles de acesso, permitindo que você restrinja quais índices e dashboards cada usuário pode ver.</p>

<pre><code class="language-yaml"># elasticsearch.yml - Configuração básica de segurança

xpack.security.enabled: true

xpack.security.transport.ssl.enabled: true

xpack.security.http.ssl.enabled: true

xpack.security.transport.ssl.keystore.path: /path/to/elastic-certificates.p12

xpack.security.transport.ssl.keystore.password: &quot;your-password&quot;

xpack.security.http.ssl.keystore.path: /path/to/elastic-certificates.p12

xpack.security.http.ssl.keystore.password: &quot;your-password&quot;

Definir senha do usuário elástico (padrão)

bin/elasticsearch-setup-passwords interactive</code></pre>

<h2>Conclusão</h2>

<p>Você aprendeu que o ELK Stack é uma solução de três camadas: o Elasticsearch indexa e armazena dados de forma distribuída e escalável, o Logstash transforma logs brutos em dados estruturados e ricos em contexto, e o Kibana oferece a visualização e exploração necessária para tomar decisões baseadas em dados. Esses três componentes trabalham em harmonia para resolver um problema crítico: como você encontra uma agulha em um palheiro de bilhões de registros de log.</p>

<p>A implementação prática exige atenção a padrões como correlação de eventos (trace IDs), gestão inteligente de índices para controlar custo e performance, e segurança adequada para proteger dados sensíveis. Começar com uma topologia simples (tudo em um servidor) é aceitável para aprendizado, mas em produção, você precisará pensar em alta disponibilidade, escalabilidade horizontal e retenção de dados.</p>

<p>O que distingue profissionais competentes é a capacidade de pensar além de &quot;apenas fazer funcionar&quot; — é entender <em>por que</em> cada componente existe, <em>como</em> ele escala, e <em>quais</em> padrões evitar. Com essa mentalidade, você conseguirá diagnosticar problemas complexos em minutos, ao invés de horas, e contribuir significativamente para a estabilidade de sistemas críticos.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html" target="_blank" rel="noopener noreferrer">Documentação Oficial do Elasticsearch</a></li>

<li><a href="https://www.elastic.co/guide/en/logstash/current/configuration.html" target="_blank" rel="noopener noreferrer">Guia de Configuração do Logstash</a></li>

<li><a href="https://www.elastic.co/guide/en/kibana/current/dashboard.html" target="_blank" rel="noopener noreferrer">Kibana User Guide - Visualizações e Dashboards</a></li>

<li><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/secure-cluster.html" target="_blank" rel="noopener noreferrer">Elastic Stack Security Essentials</a></li>

<li><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index-lifecycle-management.html" target="_blank" rel="noopener noreferrer">Index Lifecycle Management - Documentação Oficial</a></li>

</ul>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em DevOps & CI/CD

Como Usar Estratégias de Branching: Git Flow, Trunk-Based e GitHub Flow em Produção
Como Usar Estratégias de Branching: Git Flow, Trunk-Based e GitHub Flow em Produção

Introdução ao Versionamento de Código e Estratégias de Branching Quando você...

Como Usar Azure para DevOps: AKS, Azure Pipelines e Resource Groups em Produção
Como Usar Azure para DevOps: AKS, Azure Pipelines e Resource Groups em Produção

Azure Resource Groups: Fundação da Organização em Nuvem Um Resource Group (Gr...

Dominando Linux para DevOps: Filesystem, Permissões e Navegação no Terminal em Projetos Reais
Dominando Linux para DevOps: Filesystem, Permissões e Navegação no Terminal em Projetos Reais

Entendendo o Filesystem Linux O filesystem Linux é a estrutura fundamental qu...