shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script-pt] Parser em log pflogfile


From: Arkanon
Subject: Re: [shell-script-pt] Parser em log pflogfile
Date: Fri, 12 Mar 2021 09:20:11 -0300

Aí, Marcelo.

Veja só, quando substituí o zgrep pelo gzip nas soluções iniciais, acabei esquecendo do grep. Culpo a idade e a amostra, a qual deixei sem exemplos diferentes de "pass in" :-p
Aproveitei para alterar o tr em s1{2..3}, fazendo-o deletar as ocorrências de .: ao invés de substituí-las por espaço e fiz o awk devolver o resultado com espaço ao invés de ;, só pra ficar tudo no mesmo estilo, mas ainda há a diferença dos espaços iniciais, o que faz com que as soluções com e sem awk não sejam realmente equivalentes mas, como foquei na velocidade do primeiro resultado legível, optei por deixar assim.
A adição do grep aumentou levemente o tempo final das soluções, mas o reposicionamento do /dev/null para fora do for de N laços o diminuiu (percebe-se em s10, que já tinha o grep), o que mostra que "jogar fora" também tem seu custo, hehe.

s11(){ gzip -dc $F | grep "pass in" | sed -E 's/.*\.([0-9]+):.*/\1/' | sort | uniq -c | sort -rn | head -n20; }
s12(){ gzip -dc $F | grep "pass in" | grep -Eo '(\.[0-9]+\:)' | sort | uniq -c | sort -rn | head -n20 | tr -d .:; }
s13(){ gzip -dc $F | grep "pass in" | cut -d " " -f12 | cut -d. -f5 | sort | uniq -c | sort -rn | head -n20 | tr -d .:; }
s14(){ gzip -dc $F | grep "pass in" | awk '{print $12}' | cut -d. -f5 | sort | uniq -c | sort -rn | head -n20 | tr -d .:; }

s15(){ gzip -dc $F | grep "pass in" | sed -r 's/^[^>]+> ([0-9]{1,3}\.){4}([0-9]+):.*/\2/' | sort | uniq -c | sort -rn | head -n20; }
s16(){ awk '$0~"pass in" && $0!~"icmp" { split($12,out,"."); print substr(out[5], 1, length(out[5])-1) }' <(gzip -dc $F) | sort | uniq -c | sort -rn | awk 'NR <= 20 {print $1" "$2}'; }
s17(){ awk '{ split($12,out,"."); print substr(out[5], 1, length(out[5])-1) }' <(gzip -dc $F | grep "pass in") | sort | uniq -c | sort -rn | awk 'NR <= 20 {print $1" "$2}'; }

s10(){ gzip -dc $F | grep -oP "pass in.+>.+\.\K[0-9]+(?=:)" | sort | uniq -c | sort -rn | head -n20; }

F=pflogtext.0.gz
N=1000
for s in s{11..17} s10; { echo -e "\n# $s: "; $s; }; echo # apenas mostra o resultado cada solução
for s in s{11..17} s10; { echo -n "# $s: "; time for ((n=0; n<N; n++)); { $s; } &> /dev/null; } # testa efetivamente
# s11: 0m3,570s
# s12: 0m3,438s
# s13: 0m3,552s
# s14: 0m3,902s
# s15: 0m3,610s
# s16: 0m4,171s
# s17: 0m4,406s
# s10: 0m2,974s

Tomara que não tenha sobrado outra gafe :-p

Att,

Em qui., 11 de mar. de 2021 às 19:59, Arkanon <arkanon@lsd.org.br> escreveu:
Blz, Marcelo!

Comparei o tempo de execução das soluções apresentadas, incluindo uma minha na qual evitei o sed e o awk. Na falta do arquivo gigante que você tem, executei N vezes cada solução sobre a amostra.

s01(){ zgrep "pass in" $F | sed -E 's/.*\.([0-9]+):.*/\1/' | sort | uniq -c | sort -rn | head -n20; }
s02(){ zgrep "pass in" $F | grep -Eo '(\.[0-9]+\:)' | sort | uniq -c | sort -rn | head -n20 | tr '[.:]' ' '; }
s03(){ zgrep "pass in" $F | cut -d " " -f12 | cut -d "." -f5 | sort | uniq -c | sort -rn | head -n20 | tr '[.:]' ' '; }
s04(){ zgrep "pass in" $F | awk '{print $12}' | cut -d "." -f5 | sort | uniq -c | sort -rn | head -n20 | tr '[.:]' ' '; }

s05(){ zgrep "pass in" $F | sed -r 's/^[^>]+> ([0-9]{1,3}\.){4}([0-9]+):.*/\2/' | sort | uniq -c | sort -rn | head -n20; }
s06(){ awk '$0~"pass in" && $0!~"icmp" { split($12,out,"."); print substr(out[5], 1, length(out[5])-1) }' <(gzip -dc $F) | sort | uniq -c | sort -rn | awk 'NR <= 20 {print $1";"$2}'; }
s07(){ awk '{ split($12,out,"."); print substr(out[5], 1, length(out[5])-1) }' <(zgrep "pass in" $F) | sort | uniq -c | sort -rn | awk 'NR <= 20 {print $1";"$2}'; }

s08(){ zcat $F | grep -oP "pass in.+>.+\.\K[0-9]+(?=:)" | sort | uniq -c | sort -rn | head -n20; }
s09(){ zgrep -oP "pass in.+>.+\.\K[0-9]+(?=:)" $F | sort | uniq -c | sort -rn | head -n20; }
s10(){ gzip -dc $F | grep -oP "pass in.+>.+\.\K[0-9]+(?=:)" | sort | uniq -c | sort -rn | head -n20; }

F=pflogtext.0.gz
N=1000
for s in s{01..10}; { echo -n "# $s: "; time for ((n=0; n<N; n++)); { $s &> /dev/null; }; }
# s01: 0m8,082s
# s02: 0m8,191s
# s03: 0m8,339s
# s04: 0m8,470s
# s05: 0m8,048s
# s06: 0m4,286s
# s07: 0m9,036s
# s08: 0m4,854s
# s09: 0m12,296s
# s10: 0m3,083s

Nessa comparação, inicialmente a s06 foi a mais eficiente, seguida da s08 (onde evitei o sed e o awk).
Resolvi testá-la com o zgrep (criando a s09) e ele acabou com tudo... :-O
Aí reparei que a s06 usa gzip ao invés do zcat/zgrep e resolvi aplicar a ideia na s08, que virou a s10. Veja a diferença!

Então, como o gzip puro parece mais eficiente que o zcat, refiz tudo com ele (menos a s08 e a s09, que perderam a razão de existir, já que seriam iguais à s10):

s11(){ gzip -dc $F | sed -E 's/.*\.([0-9]+):.*/\1/' | sort | uniq -c | sort -rn | head -n20; }
s12(){ gzip -dc $F | grep -Eo '(\.[0-9]+\:)' | sort | uniq -c | sort -rn | head -n20 | tr '[.:]' ' '; }
s13(){ gzip -dc $F | cut -d " " -f12 | cut -d "." -f5 | sort | uniq -c | sort -rn | head -n20 | tr '[.:]' ' '; }
s14(){ gzip -dc $F | awk '{print $12}' | cut -d "." -f5 | sort | uniq -c | sort -rn | head -n20 | tr '[.:]' ' '; }

s15(){ gzip -dc $F | sed -r 's/^[^>]+> ([0-9]{1,3}\.){4}([0-9]+):.*/\2/' | sort | uniq -c | sort -rn | head -n20; }
s16(){ awk '$0~"pass in" && $0!~"icmp" { split($12,out,"."); print substr(out[5], 1, length(out[5])-1) }' <(gzip -dc $F) | sort | uniq -c | sort -rn | awk 'NR <= 20 {print $1";"$2}'; }
s17(){ awk '{ split($12,out,"."); print substr(out[5], 1, length(out[5])-1) }' <(gzip -dc $F) | sort | uniq -c | sort -rn | awk 'NR <= 20 {print $1";"$2}'; }

s10(){ gzip -dc $F | grep -oP "pass in.+>.+\.\K[0-9]+(?=:)" | sort | uniq -c | sort -rn | head -n20; }

F=pflogtext.0.gz
N=1000
for s in s{11..17} s10; { echo -n "# $s: "; time for ((n=0; n<N; n++)); { $s &> /dev/null; }; }
# s11: 0m3,452s
# s12: 0m3,252s
# s13: 0m3,414s
# s14: 0m3,699s
# s15: 0m3,418s
# s16: 0m4,221s
# s17: 0m4,155s
# s10: 0m3,015s

Com o gzip, a s06 (agora s16) passou de primeiro para último lugar, fazendo com que a s10, que evitou o sed e o awk, apresentasse o melhor desempenho.

É bem possível que com outras amostra, principalmente arquivos maiores, o comportamento se altere. Se você puder, refaça essa comparação com o seu arquivo completo. Basta alterar o valor da variável F. Não esqueça de começar com um valor mais baixo para N ;-)

Att,

Em qui., 11 de mar. de 2021 às 14:53, Marcelo Primo <marcelooprimo@yahoo.com.br> escreveu:

Salve Arkanon, tudo na paz?


Na verdade o trecho original do script tem essa referência ao protocolo icmp, mas nos arquivos de origem que analisei, não há qualquer referência à esse protocolo. Creio que quando o autor fez o script, das duas uma, ou existia alguma referência ao protocolo icmp ou ele tenha colocado esse grep a mais como uma forma de prevenção caso aparecesse qualquer coisa de icmp na lista.

Sobre as linhas que mandei, elas são a saída do arquivo sem qualquer alteração (exceto os IPs de destino). Uma amostra mais significativa seria as mesmas linhas enviadas, mas com portas e IPs de destino diferentes.

Obrigado pela disposição em ajudar.

Atenciosamente,
Marcelo

Em 11/03/2021 12:19, Arkanon escreveu:
Olá, Marcelo.

Você pode disponibilizar uma amostra mais significativa do arquivo? O comando original seleciona entradas com a string "pass in" e remove as com protocolo icmp e a amostra que você passou tem apenas exemplos positivos (com "pass in" e sem icmp).

Att,

Em qui., 11 de mar. de 2021 às 11:13, Marcelo Primo por (shell-script-pt) <shell-script-pt@nongnu.org> escreveu:
Salve, Blau!

Na minha primeira tentativa em melhorar o código fiz uns testes na saída
do comando com e sem o grep -v "icmp" e notei que não precisava, por
isso que nos meus comandos não tem esse trecho.

Atenciosamente,
Marcelo


Em 11/03/2021 10:52, Blau Araujo escreveu:
> Então...
>
> Nesse caso, eu acho mais interessante usar o zgrep na frente, passando
> a saída por pipe mesmo.
>
> Uma dúvida: e aquele outro filtro, o 'icmp'? Não precisa dele?
>
> Abraços!
>
> Blau Araujo
> -----------------------------
> https://debxp.org
> https://ask.debxp.org
> https://blauaraujo.com
>
> Em 11/03/2021 10:48, Marcelo Primo escreveu:
>> Salve Blau!
>>
>> Explicação claríssima, muito obrigado.
>>
>> Fiz uma alteração na sua sugestão e obtive um resultado similar ao
>> modelo (awk + cut), justamente trocando o gzip pelo zgrep (que, bem
>> observado por você, é onde está o gargalo).
>>
>> Vamos a linha:
>>
>> awk '{ split($12,out,"."); print substr(out[5], 1, length(out[5])-1)
>> }' <(zgrep "pass in" pflogtext.0.gz) | sort | uniq -c | sort -rn |
>> awk 'NR <= 20 {print $1";"$2}' = 2,6s
>>
>>
>> Obrigado pela ajuda.
>> Atenciosamente,
>>
>> Marcelo
>>
>> Em 11/03/2021 10:18, Blau Araujo escreveu:
>>> Salve, Marcelo!
>>>
>>>
>>> Como você não respondeu na lista (acontece... hehehe), aqui vai a
>>> explicação pra que todo mundo possa entender e opinar:
>>>
>>> Primeira parte...
>>>
>>> awk '$0~"pass in" && $0!~"icmp" { ... }' <(gzip -dc SEU_ARQUIVO)
>>>
>>> Aqui estou mandando para o AWK as linhas expandidas pelo gzip
>>> atarvés de uma substituição de processo, que resulta na abertura de
>>> um descritor de arquivos para leitura cujo "conteúdo" é a saída dos
>>> comandos entre os parêntesis:
>>>
>>> <(gzip -dc SEU_ARQUIVO)
>>>
>>> **Este deve ser o gargalo, e talvez o seu "gzcat/zcat |" antes do
>>> awk seja mais interessante.**
>>>
>>> Já a parte abaixo, é uma regra que manda o AWK processar apenas as
>>> linhas que contenham "pass in" e, ao mesmo tempo, não contenham "icmp":
>>>
>>> $0~"pass in" && $0!~"icmp" { ... }
>>>
>>> No programa (a parte entre chaves), eu uso a função 'split' pra
>>> dividir o campo $12 usando seus pontos como separador e atribuindo o
>>> resultado a um vetor de nome "out":
>>>
>>> split($12,out,".");
>>>
>>> Finalmente, eu uso a função 'substr' pra remover o ":" do final do
>>> quinto elemento do vetor obtido anteriormente, e é isso que eu mando
>>> pra saída com o 'print':
>>>
>>> print substr(out[5], 1, length(out[5])-1)
>>>
>>> O restante é o que vc faz pra agrupar e ordenar os resultados, só
>>> que, no final, eu tiro o 'head' e o 'sed' pra fazer todo o
>>> processamento final com o AWK novamente:
>>>
>>> awk 'NR <= 20 {print $1";"$2}'
>>>
>>> Aqui, 'NR <= 20' é uma regra que vai limitar a saída aos 20
>>> primeiros registros, enquanto que, no programa, eu imprimo '$1' e
>>> '$2' já concatenados com o caractere ';'...
>>>
>>>
>>>
>>> Abraços!
>>>
>>> Blau Araujo
>>> -----------------------------
>>> https://debxp.org
>>> https://ask.debxp.org
>>> https://blauaraujo.com
>>>
>>> Em 11/03/2021 09:35, Blau Araujo escreveu:
>>>> Salve!
>>>>
>>>> Eu fiquei curioso pra saber o tempo que isso levaria (ou se
>>>> funcionaria):
>>>>
>>>> ```
>>>>
>>>> awk '$0~"pass in" && $0!~"icmp" { split($12,out,"."); print
>>>> substr(out[5], 1, length(out[5])-1) }' <(gzip -dc SEU_ARQUIVO) |
>>>> sort | uniq -c | sort -rn | awk 'NR <= 20 {print $1";"$2}'
>>>>
>>>> ```
>>>>
>>>> Abraços!
>>>>
>>>> Blau Araujo
>>>> -----------------------------
>>>> https://debxp.org
>>>> https://ask.debxp.org
>>>> https://blauaraujo.com
>>>>
>>>> Em 10/03/2021 19:22, Marcelo Primo por (shell-script-pt) escreveu:
>>>>> Mar 09 00:00:03.146758 rule 12/(match) pass in on em0:
>>>>> 198.199.88.65.61953 > *192.168.1.143.9004**:* S
>>>>> 3776023135:3776023135(0) win 1024
>>>>> Mar 09 00:00:03.151840 rule 12/(match) pass in on em0:
>>>>> 198.199.88.65.61953 > *192.168.1.176.9004:* S
>>>>> 4103556202:4103556202(0) win 1024
>>>>> Mar 09 00:00:03.168233 rule 12/(match) pass in on em0:
>>>>> 203.212.200.241.58481 > *192.168.1.210.23:* S
>>>>> 1794254071:1794254071(0) win 5808 <mss 1452,sackOK,timestamp
>>>>> 63610891 0,nop,wscale 2> (DF)
>>>>> Mar 09 00:00:03.190210 rule 12/(match) pass in on em0:
>>>>> 178.175.97.53.46828 > *192.168.1.210.23:* S 700145820:700145820(0)
>>>>> win 5808 <mss 1452,sackOK,timestamp 159224881 0,nop,wscale 1> (DF)
>>>>> [tos 0x4]
>>>>> Mar 09 00:00:03.213339 rule 12/(match) pass in on em0:
>>>>> 131.159.24.205.51075 > *192.168.1.212.80:* S
>>>>> 2924909527:2924909527(0) win 65535 <sackOK,timestamp 4294967295
>>>>> 16843009,wscale
>>>>> 1,nop,opt-34:,opt-64:,opt-30:00810c0c0c0c0c0c0c0c,eol>
>>>>> Mar 09 00:00:03.263630 rule 12/(match) pass in on em0:
>>>>> 138.197.180.77.61953 > *192.168.1.194.10000:* S
>>>>> 3809871894:3809871894(0) win 1024
>>>>> Mar 09 00:00:03.394312 rule 12/(match) pass in on em0:
>>>>> 178.175.97.53.53172 > *192.168.1.210.23:* S
>>>>> 2983985618:2983985618(0) win 33941 [tos 0x4]
>>>>> Mar 09 00:00:03.500488 rule 12/(match) pass in on em0:
>>>>> 171.67.71.100.35957 > *192.168.1.249.8848:* S
>>>>> 1091778644:1091778644(0) win 65535
>>>>> Mar 09 00:00:03.637855 rule 12/(match) pass in on em0:
>>>>> 203.212.200.241.58457 > *192.168.1.210.23:* S
>>>>> 1746544785:1746544785(0) win 5808 <mss 1452,sackOK,timestamp
>>>>> 63610938 0,nop,wscale 2> (DF)
>>>>
>>>> _______________________________________________
>>>> Lista brasileira de usuários de shell script
>>>> Endereço de e-mail da lista: shell-script-pt@nongnu.org
>>>> Para se inscrever ou desinscrever acesse:
>>>> https://lists.nongnu.org/mailman/listinfo/shell-script-pt
>>>> Para ver os arquivos da lista (mensagens anteriores) e pesquisar
>>>> nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/
>>>>
>>>> NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por
>>>> favor utilize somente esta.
>>>
>>> _______________________________________________
>>> Lista brasileira de usuários de shell script
>>> Endereço de e-mail da lista: shell-script-pt@nongnu.org
>>> Para se inscrever ou desinscrever acesse:
>>> https://lists.nongnu.org/mailman/listinfo/shell-script-pt
>>> Para ver os arquivos da lista (mensagens anteriores) e pesquisar
>>> nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/
>>>
>>> NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor
>>> utilize somente esta.

_______________________________________________
Lista brasileira de usuários de shell script
Endereço de e-mail da lista: shell-script-pt@nongnu.org
Para se inscrever ou desinscrever acesse: https://lists.nongnu.org/mailman/listinfo/shell-script-pt
Para ver os arquivos da lista (mensagens anteriores) e pesquisar nelas, acesse https://lists.nongnu.org/archive/html/shell-script-pt/

NOTA: A lista anterior, no Yahoo Groups, foi *desativada*. Por favor utilize somente esta.


--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------


--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------


--
(o_  @arkanon  (Twitter)     __o
//\   arkanon@lsd.org.br   _`\<,
V_/_      www.lsd.org.br  (_)/(_)
---------------------------------

reply via email to

[Prev in Thread] Current Thread [Next in Thread]