quinta-feira, 12 de junho de 2014

xargs composto

Os logs do Apache têm uma linha para cada requisição e eu precisava saber qual a última requisição de cada um dos clientes mais frequentes (para saber o horário em que ocorreram). Cada linha do log se parece com esta:

172.16.160.30 - - [12/Jun/2014:12:02:16 -0300] "GET /a.html HTTP/1.1" 200 4712

Eu já tinha uma fórmula simples para achar os IPs dos clientes mais trabalhadores (sort | uniq -c | sort -n):

grep -Po "^\S+" access_log | sort | uniq -c | sort -n | tail -5

Assim, eu consigo os 5 IPs mais ocupados em ordem crescente.

Para cada um desses IPs, é preciso executar um novo grep, buscando apenas a última linha. Para isso, usei o xargs em combinação com o bash:

xargs -I{} bash -c "grep {}  access_log | tail -1"

Restou apenas retirar o número de ocorrências (adicionado pelo uniq -c). O grep ajuda novamente:

grep -Po "\S+$"

O -P indica uma expressão regular ao estilo do Perl e o -o indica que o resto da linha deve ser excluída. A expressão regular procura o último conjunto de caracteres que não contém um espaço. O primeiro grep usava uma expressão semelhante para achar o IP (primeira coluna do arquivo).

O resultado é mais assustador que a soma das partes:

grep -Po "^\S+" access_log | sort | uniq -c | sort -n | tail -5 \
  | grep -Po "\S+$" \
  | xargs -I{} bash -c "grep {}  access_log | tail -1"

Estou pensando se não seria prático descartar a ferramenta cara de BI e trocá-la por arquivos texto e shell.

Nenhum comentário: