O óbvio é tail -f app.log db.log, mas há uma armadilha em produção: quando logrotate gira o arquivo, ele o renomeia e cria um novo, -f mantém aberto o descriptor de arquivo antigo e você fica olhando para uma tela congelada. A solução é um carácter: -F reabre o arquivo por nome em vez de por inode. Aqui está quando usar cada variante.
1. Mostrar ambos os arquivos com headers separando-os
$ clai mostra ambos estes logs ao mesmo tempo→ tail -n +1 app.log db.log==> app.log <==line A1==> db.log <==line B1
Quando você consulta vários arquivos ao mesmo tempo, tail imprime automaticamente headers como ==> nome <== para mostrar qual é a origem de cada linha. Isso é crucial: sem ele você não saberá de qual log veio cada linha.
2. Seguir ambos os logs conforme novas linhas chegam
$ clai segue ambos os logs enquanto novas linhas são escritas→ tail -f app.log db.log
O header é impresso novamente toda vez que a origem muda. Enquanto um arquivo está sendo escrito, você não vê o header; quando o outro arquivo recebe uma linha, o header aparece.
3. Sobreviver à rotação de log e continuar lendo
$ clai segue o log para que não fique mudo após a rotação→ tail -F /var/log/app/app.log
Esta é a linha que importa. -f mantém aberto o descriptor de arquivo: depois que logrotate renomeia o arquivo e cria um novo, tail -f continua lendo a cópia renomeada e nunca vê novas linhas. -F observa o nome do arquivo e reabre o arquivo. Sempre use -F em produção.
4. Etiquetar cada linha com o nome da origem
$ clai mostra ambos os logs misturados mas etiqueta cada linha com o nome do arquivo→ for f in app.log db.log; do tail -F "$f" | sed "s/^/[$f] /" & done; wait
Headers em bloco ficam incômodos quando os logs são escritos simultaneamente. Um prefixo em cada linha é mais fácil de ler. O & inicia cada tail em segundo plano, e wait mantém o shell em execução.
5. Observar todos os arquivos de log em um diretório, incluindo os criados depois
$ clai segue todos os arquivos de log no diretório→ tail -F /var/log/app/*.log
O shell expande o glob uma única vez, na inicialização. Arquivos criados depois não serão incluídos: você teria que reiniciar.
6. Quando você precisa de uma interface real com painéis
$ clai mostra vários logs em painéis separados→ multitail /var/log/syslog /var/log/auth.log
multitail desenha painéis com destaque de sintaxe e filtros. Para triagem de incidentes com quatro logs de uma vez, isso é notavelmente melhor do que um stream. Instale separadamente.
Pegadinhas
-fe-Fsó diferem em rotação. Antes da rotação acontecer, não há diferença, então o hábito de usar-fnão é punido. Você é punido no momento exato em que espera uma linha de log durante um incidente e ela para de chegar.tail -fpela rede não funciona bem. Em NFS, as alterações podem não chegar ao cliente. Veja o log na máquina onde está sendo escrito.- As linhas podem se embaralhar. Dois processos escrevendo em um stream não são sincronizados. Para entender a ordem dos eventos, leia os timestamps dentro das linhas, não a ordem de saída.
Perguntas relacionadas
Como inicio a leitura a partir de uma linha específica em vez do final? tail -n +100 file começa na linha 100, tail -c +1000 começa no byte 1000.
Como sigo um log e o filtro ao mesmo tempo? tail -F app.log | grep --line-buffered ERROR. Sem --line-buffered, grep armazena em buffer a saída e as linhas chegam com atraso.
Por que journalctl é melhor que tail para serviços? Entende sobre rotação, pode filtrar por unidade e nível de log, e não depende de onde o serviço escreve.
Veja também
- Read a service's logs with journalctl
- Sweep old logs and backups with one sentence
- Grep with exclusions
Pare de memorizar edge cases de tail e logrotate — descreva o que precisa ver e o CliAI escreve o comando. Instale em uma linha.