Logs em containers Docker
1. Fundamentos de Logs no Docker
O Docker coleta automaticamente tudo que um container envia para stdout (saída padrão) e stderr (saída de erro padrão). O comando principal para acessar esses logs é docker logs.
# Visualizar logs do container
docker logs meu-container
# Seguir logs em tempo real (como tail -f)
docker logs --follow meu-container
# Exibir apenas as últimas 50 linhas
docker logs --tail 50 meu-container
# Adicionar timestamps a cada linha
docker logs --timestamps meu-container
# Combinar opções: últimos 100 logs com timestamps
docker logs --tail 100 --timestamps meu-container
É crucial entender que logs escritos em arquivos dentro do container (ex: /var/log/app.log) não são capturados pelo docker logs. O Docker gerencia apenas o que chega via stdout/stderr. O armazenamento local dos logs fica em /var/lib/docker/containers/[ID]/[ID]-json.log quando usando o driver padrão json-file.
2. Drivers de Log do Docker
O Docker oferece diversos drivers de log para rotear os logs dos containers. A configuração global é feita no arquivo /etc/docker/daemon.json:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Principais drivers e seus usos:
| Driver | Descrição | Ideal para |
|---|---|---|
json-file |
Padrão, logs em arquivos JSON locais | Desenvolvimento, testes |
journald |
Envia logs para systemd-journald | Ambientes Linux com systemd |
syslog |
Envia para syslog local ou remoto | Infraestrutura legada |
awslogs |
Envia para Amazon CloudWatch | Ambientes AWS |
gelf |
Formato Graylog Extended Log | Graylog, Elasticsearch |
fluentd |
Envia para Fluentd | Pipelines de logging centralizado |
Para configurar por container:
docker run --log-driver syslog --log-opt syslog-address=udp://192.168.1.100:514 nginx
Prós e contras em produção: json-file é simples mas não escala; fluentd e awslogs oferecem melhor centralização; journald integra bem com ferramentas Linux nativas.
3. Boas Práticas de Logging em Containers
Aplicações em containers devem seguir o princípio 12-factor: logs como fluxo de eventos, sempre para stdout/stderr.
# Ruim: escrever em arquivo interno
python app.py >> /var/log/app.log 2>&1
# Bom: escrever direto no stdout
python app.py
Estruturação de logs em JSON facilita análise posterior:
# Logs não estruturados (difícil de parsear)
2024-01-15 10:30:45 ERRO conexão falhou com banco
# Logs em JSON (fácil de filtrar com jq)
{"timestamp":"2024-01-15T10:30:45Z","level":"ERROR","service":"api","message":"conexão falhou com banco","db_host":"db-prod-01"}
Controle de verbosidade: evite logs de debug em produção. Configure níveis via variáveis de ambiente:
docker run -e LOG_LEVEL=warn minha-app
4. Gerenciamento de Tamanho e Rotação de Logs
Sem rotação, logs podem consumir todo o disco. Configure limites no driver json-file:
# Configuração no daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "5"
}
}
Para containers já rodando, faça limpeza manual:
# Verificar tamanho dos logs
du -sh /var/lib/docker/containers/*/*-json.log
# Truncar logs de um container específico
truncate -s 0 /var/lib/docker/containers/[ID]/[ID]-json.log
# Usar docker logs com tail para arquivos corrompidos
docker logs --tail 100 container-problema > logs_recentes.txt
Riscos de disco cheio: Um container com loop infinito de logs pode travar o host. Estratégias de mitigação:
- Monitorar uso de disco via Prometheus/node_exporter
- Configurar rotação automática com logrotate para o diretório do Docker
- Usar drivers remotos que não acumulam logs localmente
5. Coleta Centralizada de Logs com Docker
Para ambientes com múltiplos hosts, a coleta centralizada é essencial. Exemplo com Fluentd:
# Executar container com driver fluentd
docker run --log-driver fluentd --log-opt fluentd-address=localhost:24224 nginx
# Configuração do Fluentd (fluent.conf)
<source>
@type forward
port 24224
</source>
<match docker.**>
@type elasticsearch
host elasticsearch-prod
port 9200
logstash_format true
</match>
Para aplicações legadas que escrevem em arquivos, use sidecar containers:
# docker-compose.yml
services:
app-legada:
image: minha-app-antiga
volumes:
- logs-volume:/var/log/app
log-collector:
image: fluent/fluentd
volumes:
- logs-volume:/logs
command: fluentd -c /fluentd/etc/fluent.conf
6. Logs em Ambientes Kubernetes
No Kubernetes, kubectl logs substitui docker logs. Diferenças fundamentais:
# Docker
docker logs container-id
# Kubernetes - logs de um pod
kubectl logs pod-name
# Kubernetes - logs de container específico em pod multi-container
kubectl logs pod-name -c container-name
# Seguir logs em tempo real
kubectl logs -f pod-name
# Últimas N linhas
kubectl logs --tail=100 pod-name
Para logs de pods com múltiplos containers, o K8s suporta --all-containers=true (v1.14+):
kubectl logs --all-containers=true deployment/api
Ferramentas de logging no ecossistema K8s:
- Fluentd + Elasticsearch + Kibana (EFK): Stack clássica
- Loki + Promtail + Grafana: Leve, sem indexação pesada
- Datadog, New Relic: SaaS com agentes DaemonSet
7. Segurança e Auditoria de Logs
Logs podem conter dados sensíveis. Nunca logue senhas, tokens ou dados pessoais:
# RUIM - token exposto no log
{"user":"admin","token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
# BOM - token mascarado
{"user":"admin","token":"***MASCARADO***"}
Para auditoria do Docker daemon, habilite logs do dockerd:
# Iniciar dockerd com debug e logs detalhados
dockerd --log-level debug --log-opt max-size=50m
# Visualizar logs do daemon
journalctl -u docker.service --since "1 hour ago"
Controle de acesso: apenas usuários no grupo docker podem executar docker logs. Para logs de volumes compartilhados, use permissões Unix:
# Volume com permissões restritas
docker run -v /host/logs:/app/logs:ro minha-app
8. Monitoramento e Troubleshooting com Logs
Correlacione logs com métricas para troubleshooting eficiente:
# Identificar OOM killer
docker logs container-oom | grep -i "killed"
# Verificar logs de healthcheck com timestamps
docker logs --since 5m healthcheck-container
# Combinar docker stats com logs
docker stats container-problema --no-stream &
docker logs --follow container-problema
Comandos úteis para análise:
# Filtrar erros das últimas 2 horas
docker logs --since 2h app-production | grep -i error
# Analisar logs JSON com jq
docker logs api-container | jq 'select(.level=="ERROR") | {message, timestamp}'
# Contar ocorrências de erro por minuto
docker logs app --since 1h | grep "ERROR" | cut -c1-16 | sort | uniq -c
Erros comuns em containers:
- OOM: Container morto pelo kernel. Verifique docker inspect e logs do host
- Healthcheck falhando: Logs mostram timeout ou resposta inesperada
- Crashes recorrentes: Use docker logs --tail 20 --timestamps para ver o último erro antes do crash
Referências
- Docker Logs Documentation — Documentação oficial do comando docker logs e todas as suas opções
- Docker Logging Drivers — Guia completo sobre drivers de log e configuração no daemon.json
- 12 Factor App: Logs — Princípio fundamental sobre logs como fluxo de eventos em aplicações cloud-native
- Kubernetes Logging Architecture — Documentação oficial sobre logging em clusters Kubernetes
- Fluentd Docker Log Driver — Tutorial prático de integração do Docker com Fluentd para coleta centralizada
- Elastic Stack Docker Logging — Guia para enviar logs Docker para Elasticsearch usando Filebeat
- Loki Docker Logging — Documentação do driver Docker para Loki, ideal para Grafana