Logging centralizado
LidoNesta aula, exploramos o logging centralizado, uma prática essencial em DevOps para coletar, agregar e analisar logs de múltiplos serviços. Abordamos logs estruturados, ferramentas de agregação como ELK e Loki, políticas de retenção e boas práticas, com exemplos práticos em bash.
O logging centralizado é uma prática fundamental em ambientes DevOps, especialmente em arquiteturas de microsserviços e contêineres. Com a crescente complexidade dos sistemas, cada serviço gera seus próprios logs, o que torna a depuração e o monitoramento extremamente difíceis se não houver uma forma de agregar e correlacionar essas informações. Nesta aula, vamos explorar o conceito de logging centralizado, desde a estruturação dos logs até a implementação de pipelines de agregação e políticas de retenção, passando por ferramentas populares como ELK Stack e Loki.
Vamos começar entendendo por que logs estruturados são essenciais para a centralização, depois mergulharemos nas ferramentas de agregação, discutiremos estratégias de retenção e finalizaremos com boas práticas que você pode adotar imediatamente em seus projetos.
Logs estruturados
Logs estruturados são registros de eventos que seguem um formato predefinido, como JSON, em vez de texto livre. Isso permite que ferramentas de agregação e análise façam parsing automático e extraiam campos específicos, como timestamp, nível de severidade, nome do serviço, ID de correlação, entre outros. Em contraste, logs não estruturados são difíceis de filtrar e correlacionar, exigindo expressões regulares complexas e muitas vezes falhas.
Por exemplo, um log tradicional em texto livre pode ser:
2025-01-27 10:15:30 ERROR Failed to connect to databaseUm log estruturado equivalente em JSON seria:
{ "timestamp": "2025-01-27T10:15:30Z", "level": "ERROR", "message": "Failed to connect to database", "service": "user-service", "db": "postgres" }Com logs estruturados, você pode facilmente consultar todos os erros de um serviço específico, ou todos os logs que mencionam um determinado banco de dados, sem precisar de parsing manual. Ferramentas como Elasticsearch e Loki indexam esses campos automaticamente, permitindo buscas rápidas e eficientes.
Para gerar logs estruturados, você pode usar bibliotecas de logging em sua linguagem de programação que suportam formatação JSON, como python-json-logger para Python, logrus para Go, ou pino para Node.js. Em bash, você pode usar ferramentas como jq para construir JSON a partir de comandos.
Exemplo de geração de log estruturado em bash usando jq:
#!/bin/bash
log() {
local level="$1"
local message="$2"
echo "$(jq -n --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg lvl "$level" --arg msg "$message" --arg svc "my-service" '{timestamp: $ts, level: $lvl, message: $msg, service: $svc}')"
}
log "INFO" "Service started"
log "ERROR" "Database connection failed"Agregação (ELK, Loki - visão geral)
A agregação de logs envolve coletar logs de todas as fontes (servidores, contêineres, aplicações) e centralizá-los em um único local para busca, análise e alertas. Duas das stacks mais populares são o ELK Stack (Elasticsearch, Logstash, Kibana) e o Grafana Loki. Vamos entender cada uma.
ELK Stack é composto por:
- Elasticsearch: um mecanismo de busca e análise baseado em Lucene, que armazena e indexa os logs.
- Logstash: uma ferramenta de ingestão de dados que coleta logs de múltiplas fontes, transforma e envia para o Elasticsearch.
- Kibana: uma interface web para visualizar e consultar os dados no Elasticsearch.
O fluxo típico é: aplicações enviam logs (via Filebeat ou diretamente) para o Logstash, que os processa e envia para o Elasticsearch, onde são indexados. O Kibana permite criar dashboards e consultas. O ELK é poderoso, mas pode ser pesado em termos de recursos, exigindo configuração e manutenção.
Grafana Loki é uma alternativa mais leve, projetada especificamente para logs, inspirada no Prometheus. Ele usa um armazenamento baseado em objetos e indexa apenas os metadados (labels), não o conteúdo completo, o que o torna mais eficiente em custo. O Loki é frequentemente usado com o Grafana para visualização e com o Promtail para coleta de logs.
Exemplo de configuração do Loki para receber logs de um arquivo usando Promtail:
# promtail.yaml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*.logAmbas as ferramentas têm seus prós e contras. O ELK oferece recursos avançados de busca e análise, mas é mais complexo. O Loki é mais simples e integra-se bem com o Grafana, mas tem limitações em consultas complexas. A escolha depende do seu contexto e necessidades.
Retenção
Políticas de retenção definem por quanto tempo os logs devem ser armazenados. Isso é crucial por vários motivos: conformidade com regulamentações (como GDPR ou LGPD), custos de armazenamento, e necessidade de dados históricos para auditoria e análise de tendências. Uma boa política de retenção equilibra a necessidade de dados com os custos.
Em ambientes de produção, é comum definir retenção por níveis: logs quentes (hot) para os últimos dias, logs mornos (warm) para semanas, e logs frios (cold) para meses ou anos, usando diferentes tipos de armazenamento. Ferramentas como Elasticsearch oferecem índices com políticas de ciclo de vida (ILM) que automatizam essa transição.
Exemplo de política de retenção no Elasticsearch usando ILM:
# Criar política ILM
PUT _ilm/policy/logs_policy
{
"policy": {
"phases": {
"hot": {
"actions": {
"rollover": {
"max_size": "50GB",
"max_age": "7d"
}
}
},
"delete": {
"min_age": "30d",
"actions": {
"delete": {}
}
}
}
}
}No Loki, a retenção é configurada no arquivo de configuração, definindo o período de retenção por tenant ou globalmente:
# loki.yaml
limits_config:
retention_period: 720h # 30 dias
chunk_store_config:
max_look_back_period: 720h
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24hÉ importante monitorar o uso de armazenamento e ajustar as políticas conforme necessário. Lembre-se de que logs são dados valiosos, mas também podem se tornar um passivo se não forem gerenciados adequadamente.
Boas práticas
Adotar boas práticas de logging centralizado pode evitar muitos problemas. Aqui estão algumas recomendações:
- Use logs estruturados: como vimos, isso facilita a análise automática.
- Inclua IDs de correlação: para rastrear uma requisição através de múltiplos serviços, adicione um ID único (como
request_id) a todos os logs daquela requisição. - Defina níveis de log claros: use DEBUG, INFO, WARN, ERROR de forma consistente e evite logs excessivos em produção.
- Centralize desde o início: não espere o sistema crescer para implementar logging centralizado; comece em projetos pequenos.
- Monitore o pipeline de logs: garanta que os logs estão chegando ao destino e que não há gargalos ou perdas.
- Proteja os logs: logs podem conter dados sensíveis; use criptografia em trânsito e em repouso, e controle o acesso.
- Automatize a configuração: use ferramentas de IaC (Infraestrutura como Código) para gerenciar a configuração do stack de logs.
Além disso, é importante testar a pipeline de logs regularmente, simulando falhas e verificando se os logs são coletados corretamente. Documente os formatos e políticas para que a equipe esteja alinhada.
Referências
- O que é ELK Stack - Documentação oficial Elastic
- Grafana Loki - Site oficial
- Gerenciamento do ciclo de vida de índices no Elasticsearch
- Documentação de configuração do Loki
- Logging de contêineres no Docker
- 12-factor app - Logs
- Boas práticas de logging estruturado
Exercícios
- Exercício 1: Crie um script em bash que gere logs estruturados em JSON para um serviço fictício. O script deve ter uma função
logque aceita nível e mensagem, e deve incluir timestamp, serviço e nível. Teste com pelo menos 3 mensagens de níveis diferentes.
#!/bin/bash
log() {
local level="$1"
local message="$2"
echo "$(jq -n --arg ts "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --arg lvl "$level" --arg msg "$message" --arg svc "my-service" '{timestamp: $ts, level: $lvl, message: $msg, service: $svc}')"
}
log "INFO" "Service started"
log "WARN" "Memory usage high"
log "ERROR" "Failed to connect to database"limits_config:
retention_period: 168h # 7 dias
chunk_store_config:
max_look_back_period: 168h
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h{ "timestamp": "2025-01-27T10:15:30Z", "level": "ERROR", "message": "Failed to connect to database", "service": "unknown" }Observações finais
O logging centralizado é um pilar da observabilidade em DevOps. Dominar logs estruturados, ferramentas de agregação e políticas de retenção permite que você mantenha sistemas saudáveis e diagnosticáveis. Lembre-se de que a implementação deve ser iterativa: comece simples, monitore, e evolua conforme a necessidade. Pratique com as ferramentas em ambientes de teste e sempre mantenha a segurança dos dados em mente.