Analisando Logs no Linux
Published:
Neste post irei explicar e mostrar algumas idéias de parâmetros para melhor analisar logs no Linux.
Tive a idéia de criar este post quando comecei a ler o artigo de JoãoVRMaia, foi quando então decidi não terminar de ler, e sim criar um próprio para aprender ainda mais :)
Como Funciona os Logs?
Bom, podemos definir o arquivo de log como uma timeline (linha do tempo) do que você fez, ou está fazendo. Basicamente quando você está logando em uma máquina Linux, instalando algo, criando ou remover arquivo, tudo isto é anotado em um arquivo de log.
Ferramentas: cat, awk, sed, sort, uniq, tail, head e cut.
Ferramentas | Funções |
---|---|
cat | lê arquivos sequencialmente |
grep, egrep, fgrep | ferramenta de pesquisa |
awk | linguagem de script usada para manipular dados |
sed | editor de fluxo de texto, pode-se procurar, trocar e deletar palavras de um arquivo. |
sort | organiza palavras iguais |
uniq | se o sort organiza, o uniq “unifica” as palavras iguais |
tail | lê a saida da parte final do arquivo (parte de baixo) |
head | lê a saida da parte inicial do arquivo |
Bom, Vamos lá?
Grep, Egrep e Fgrep
Essa é uma ferramenta de pesquisa que pode ser utilizada para diversas funcionalidades, desde a procura por strings no nome de arquivos ou pastas, ou até mesmo no conteúdo do arquivo.
o Egrep (extended Grep) e Fgrep (Fixed Grep) são “variantes” do grep (global regular expression print).
egrep ou grep -E Uma versão mais eficiente para pesquisar por expressões regulares.
fgrep ou grep -F Uma versão mais eficiente para pesquisar por padrões de strings. Com o fgrep eu não preciso do escape.
Exemplo prático:
Vou ler o arquivo de configuração para conexão via SSH.
$ cat /etc/ssh/sshd_config | grep -i "port"
#Port 22
-i = ignore case (não diferencia maiúsculo de minúsculo)
Ele me retorna a linha que possui a palavra port dentro do arquivo sshd_config, legal né?
Bom, vamos um pouquinho mais afundo. Lembra que falei que o egrep ou grep -E é eficiente com expressões regulares? Vamos ao exemplo!
Quero remover as linhas comentadas ”#” do arquivo para saber tudo que está setado como configuração do sshd.
cat /etc/ssh/sshd_config | egrep -v "^#|^$"
-v = inverter o resultado.
^ = Começo da linha
$ = Final da linha
Ficou então, tudo que tenha no começo da linha o caracter # você não mostra, pois coloquei o parâmetro -v.
Demais!! :)
Irei agora criar uma arquivo com letras e números para filtrarmos a saída.
$ echo "123456789 abcdefgh 12ab34cd" > teste.txt
Vou adicionar mais uma linha com o mesmo conteúdo para dificultar.
$ echo "123456789 abcdefgh 12ab34cd" >> teste.txt
Neste utilizei dois sinais de maior ‘»’ para não subinscrever o que já havia escrito anteriormente.
Resultado final do arquivo:
$ cat teste.txt
123456789 abcdefgh 12ab34cd
123456789 abcdefgh 12ab34cd
Awk
O Awk é bem bacana que ele ajuda a gente a printar na saída colunas específicas do arquivo, vamos ao exemplo:
$ cat teste.txt | awk '{print $1}'
123456789
123456789
Neste caso pedi para ele me retornar a primeira coluna do arquivo teste.txt.
Ah, já estava me esquecendo!
O pipe “|” serve para você enviar a saída do primeiro comando para o segundo, como se fosse uma junção.
Da pra fazer ainda mais, vamos dizer que você quer acrescentar informações na saída do comando, sendo assim, as aspas podem nos ajudar!
cat teste.txt | awk '{print "hellow!! "$1}'
hellow!! 123456789
hellow!! 123456789
Sed
Já o sed, sempre gostei bastante de utiliza-lo para replace (substituição de palavras ou frases), vamos ao exemplo prático?
$ sed 's/.*9/aaaaaaaa/g' teste.txt
Aprendi este comando, pensando ele da seguinte forma: ‘s/de/para/g’, aprendi isto com um antigo colega de trabalho @Bruno, já aproveito para agradece-lo hehe.
Como neste caso utilizei regex, vou descreve-lo abaixo para melhor entendimento:
- . = qualquer caracter
- * = tudo
Temos então, do inicio do arquivo qualquer caracter até o numeral 9, resultado:
$ sed 's/.*9/aaaaaaaa/g' teste.txt
aaaaaaaa abcdefgh 12ab34cd
aaaaaaaa abcdefgh 12ab34cd
Uniq
O uniq é bem simples e bacana de utilizar, se pegarmos o nosso arquivo inicial por exemplo e adequarmos o Pipe com o comando uniq, ficará somente uma linha, pois ele unifica tudo que temos de igual.
cat teste.txt | uniq
123456789 abcdefgh 12ab34cd
Sort
Para melhor entendimento deste comando, vamos adicionar mais uma linha em nosso arquivo, veja abaixo:
$ echo "abb" >> teste.txt
$ echo "ccc" >> teste.txt
$ echo "abb" >> teste.txt
Resultado:
$ cat teste.txt
123456789 abcdefgh 12ab34cd
123456789 abcdefgh 12ab34cd
abb
ccc
abb
Veja que legal, o resultado com o comando sort:
cat teste.txt | sort
123456789 abcdefgh 12ab34cd
123456789 abcdefgh 12ab34cd
abb
abb
ccc
Ele organiza o ‘abb’ para cima, se utilizamos o comando uniq em conjunto, a saída fica da seguinte forma:
$ cat teste.txt | sort | uniq
123456789 abcdefgh 12ab34cd
abb
ccc
Tudo unificado e organizado, demais!!
Bom, Vamos para um exemplo de uma situação real?
Vamos supor que você gostaria de analisar os logs de um servidor Apache, pois acredita que pode estar havendo algum problema.
Então vamos até a pasta dos logs do Apache Server:
$ cd /var/log/httpd/
Lembrando que a pasta pode mudar dependendo da versão ou configuração
Como quero ver o log em real time, irei utilizar o comando tail com o parâmetro -f.
$ tail -f access.log
Resultado:
172.17.0.1 - - [10/Aug/2020:13:25:35 +0000] "GET / HTTP/1.1" 200 45
- 172.17.0.1 = Ip de origem da requisição
- [10/Aug/2020:13:25:35 +0000] = Tudo que envolva data
- GET = Metodo da requisição
- HTTP/1.1 = Protocolo com a versão usado pelo cliente
- 200 = Resultado da requisição
- 45 = tamanho do objeto retornado ao cliente.
Neste caso eu gostaria de saber somente o ip de origem das requições, portanto, posso utilizar o awk.
$ tail -f access.log awk '{print $1}'
Acrescentando infos no log:
$ tail -f access.log | sed 's/^/Ip de Origem = /g' | awk '{print $1,$2,$3,$4,$5,"Datas = "$8,$9}'
Resultado:
Ip de Origem = 172.17.0.1 Datas = [10/Aug/2020:13:23:13 +0000]
Bom, estes foram alguns exemplos básicos de como podemos utilizar algumas ferramentas, existem outras diversas. Aprendi bastante escrevendo este artigo, espero que eu tenha ajudado de alguma forma. :D
Obrigado por ler!