← Voltar para o Blog

LLM para triagem de log: útil sem virar gerador de alarme falso

Pedir para um modelo "analisar os logs e dizer o que está errado" produz texto convincente e inútil. O uso que funciona é mais modesto, mais barato e muito mais confiável.

Equipe EasyOps Cloud · · 7 min de leitura

A ideia é sedutora: jogar o log no modelo e perguntar o que está acontecendo. O resultado costuma ser um texto bem escrito, organizado em tópicos, com aparência de diagnóstico — e frequentemente errado.

O problema não é o modelo ser ruim. É a tarefa estar mal formulada. "Analise estes logs" pede uma conclusão sobre um sistema que o modelo não conhece, a partir de uma amostra que provavelmente não contém a causa. Ele então produz a resposta mais plausível, que é exatamente o que você não quer em diagnóstico.

Existe um conjunto de usos que funciona bem. Todos têm em comum uma coisa: o modelo transforma texto em vez de decidir o que está errado.

Por que o resumo genérico falha

Três razões estruturais, e vale entendê-las antes de montar qualquer fluxo.

A causa raramente está na amostra. O log tem gigabytes; você envia dois mil tokens. A linha que explica o incidente costuma estar minutos antes do sintoma, e não no trecho que você recortou por conter a palavra error.

O modelo não conhece o normal do seu sistema. Uma exceção que aparece cem vezes por dia há dois anos e não incomoda ninguém será apresentada como problema crítico. Sem linha de base, não há como distinguir sinal de rotina.

Plausível não é verdadeiro. Diante de sinais ambíguos, o modelo produz a explicação mais comum para aquele padrão — que pode não ser a sua. E o texto sai com o mesmo tom de confiança em ambos os casos, o que é pior do que uma resposta hesitante.

O efeito somado é caro: alarme falso corrói a confiança na ferramenta. Depois de três alertas errados, ninguém lê o quarto — inclusive o correto.

Filtre antes com ferramenta determinística

O princípio que faz tudo funcionar: o modelo não deve decidir o que é relevante. Ele deve receber o que já foi selecionado por regra e transformar em algo mais legível.

Fazer a seleção com as ferramentas de sempre é mais barato, mais rápido e não erra:

# Só o que é erro de verdade, na janela do incidente
journalctl -u meuapp --since '30 min ago' -p err --no-pager

# Agrupar por assinatura, que é o que revela padrão
journalctl -u meuapp --since '1 hour ago' -p err --no-pager \
  | sed -E 's/[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:.]+Z?//; s/[0-9a-f]{8,}/ID/g; s/[0-9]+/N/g' \
  | sort | uniq -c | sort -rn | head -20

Aquele sed faz o trabalho pesado: remove data, identificador e número, deixando a forma da mensagem. O resultado é uma contagem por tipo de erro, que já responde à maior parte das perguntas sem modelo nenhum.

É a partir daí — vinte linhas agrupadas e contadas — que o modelo tem o que fazer.

Os quatro usos que funcionam

Explicar mensagem obscura. Erro de biblioteca, código de kernel, exceção de driver. O modelo traduz para linguagem comum e sugere onde olhar. Aqui ele está recuperando conhecimento geral, que é exatamente onde é forte.

Agrupar por semelhança semântica. Cinco mensagens com texto diferente descrevendo a mesma falha. O uniq não junta, o modelo junta. Útil quando a aplicação gera erros com formatação inconsistente.

Escrever o resumo do incidente. Depois de resolvido, transformar a sequência de eventos em narrativa cronológica para o registro. O modelo é bom em texto, e essa é uma tarefa de texto — feita a partir de fatos que você já apurou.

Sugerir o comando seguinte. Dado um erro, propor o que investigar. Aqui vale a regra de ouro: ele sugere, você executa. Nunca o contrário.

Repare no padrão: em nenhum deles o modelo decide se há um problema. Ele reformula informação que já passou por um filtro confiável.

O prompt que reduz invenção

Três instruções mudam muito a qualidade da resposta:

  • Dar o contexto do sistema. Que aplicação é, qual pilha, o que é esperado. Sem isso ele adivinha a arquitetura.
  • Exigir citação da linha. "Para cada afirmação, cite a linha do log que a sustenta." Reduz drasticamente conclusão sem base, porque força o modelo a apontar evidência.
  • Autorizar a incerteza. "Se o log não permitir concluir, diga que não permite e liste o que seria necessário." Sem essa permissão explícita, o modelo sempre responde alguma coisa.

Um esqueleto que funciona:

Contexto: API Node.js com Postgres, atrás de nginx, em VPS Linux.
Comportamento normal: ~50 req/s, latência p95 de 120 ms.

Abaixo, erros da última hora agrupados por assinatura, com contagem.

Para cada grupo: o que a mensagem significa, e qual comando eu
deveria rodar para confirmar a hipótese.
Cite a linha que sustenta cada afirmação.
Se não for possível concluir, diga isso explicitamente.

<dados>

Note que ele pede comando para confirmar, não conclusão. É a diferença entre uma ferramenta que acelera investigação e uma que substitui investigação — e só a primeira é confiável.

Para detectar anomalia, estatística ganha do modelo

Existe uma tentação natural: se o modelo entende texto, que ele descubra o que está fora do normal. Na prática, a contagem simples resolve melhor, mais barato e sem inventar.

O que caracteriza anomalia em log é quase sempre quantitativo — uma assinatura de erro que não existia ontem, ou uma que existia e multiplicou. Isso é comparação de duas listas:

#!/usr/bin/env bash
# Assinaturas de erro que apareceram hoje e não existiam ontem
assinaturas() {
  journalctl -u meuapp --since "$1" --until "$2" -p err --no-pager \
    | sed -E 's/^.{0,32}//; s/[0-9a-f]{8,}/ID/g; s/[0-9]+/N/g' \
    | sort -u
}

comm -13 \
  <(assinaturas '2 days ago' '1 day ago') \
  <(assinaturas '1 day ago' 'now')

O que sai daí é uma lista curta de erros genuinamente novos — e essa lista, sim, vale mandar para o modelo explicar. A ordem importa: estatística encontra, modelo explica. Invertida, você paga para o modelo ler milhares de linhas e recebe uma opinião sobre a amostra que coube.

O mesmo raciocínio vale para volume. Um alerta disparado quando a contagem de erros por minuto ultrapassa três desvios da média da semana é mais confiável, mais rápido e infinitamente mais barato que qualquer análise semântica — e não tem como alucinar.

Custo e privacidade

Log é volumoso e contém dado sensível com frequência maior do que se imagina: token em URL, e-mail de usuário, endereço IP, corpo de requisição registrado em modo de depuração.

Duas consequências práticas:

  • Nunca envie log bruto para API externa. Filtre e anonimize antes. O agrupamento por assinatura mostrado acima já ajuda muito, porque o sed remove identificadores.
  • O volume é o custo. Enviar log inteiro é caro e piora o resultado. Vinte linhas agrupadas custam centavos e funcionam melhor que dez mil linhas cruas.

Se o log contiver dado que não pode sair, esta é uma das tarefas em que um modelo pequeno local resolve bem — a exigência de qualidade é modesta, e a decisão entre API e modelo próprio pende para o lado de dentro quando o dado é o critério. Vale ler junto o que realmente expõe dado em integrações com IA: log é justamente o vetor mais subestimado.

O que continua sendo trabalho de gente

Vale ser direto sobre o limite, porque é onde as expectativas costumam quebrar.

O modelo não sabe que o pico de erro coincidiu com o deploy das 14h. Não sabe que aquele serviço depende de uma integração que cai toda terça. Não sabe que o cliente que reclamou usa a funcionalidade de um jeito específico. Esse conhecimento é do time, e é ele que resolve incidente.

O que a ferramenta entrega é tempo: menos minutos lendo texto repetitivo, tradução rápida de mensagem obscura, e o rascunho do registro pós-incidente pronto para revisão.

E há um pré-requisito que nenhuma IA substitui: log que preste. Antes de investir nesse fluxo, vale garantir que a aplicação registra com nível adequado, com identificador de requisição para correlacionar, em formato consistente e com retenção suficiente. Modelo nenhum extrai informação de log que não foi escrito — e um journald bem configurado com retenção definida vale mais, na prática, que qualquer camada de IA por cima.

O teste que resolve a dúvida sobre por onde começar é simples: pegue o último incidente e pergunte se, relendo o log com calma, seria possível reconstruir o que aconteceu. Se a resposta for não, o problema está na instrumentação, e nenhuma camada de análise vai contorná-lo. Se for sim mas tenha levado horas, aí sim existe tempo real a ser economizado — e é exatamente esse o espaço em que essa ferramenta entrega valor.

Suba um servidor em minutos

Preço em real, suporte em português e dados no Brasil.

Criar conta