DEV Community

Cover image for Usando cURL para diagnóstico de problemas
Marcelo Andrade
Marcelo Andrade

Posted on

Usando cURL para diagnóstico de problemas

"O sistema está lento".

Que sysadmin/devops/SRE (ou seja lá qual o branding moderno para o responsável pela infra) não odeia essa declaração, porque ela não te diz absolutamente nada.

A aplicação está lenta? Ou é o servidor de aplicação? Ou o balanceador? Ou o storage?

E se a aplicação for distribuída, o problema fica 100 vezes maior.

A maneira moderna de fazer diagnóstico deste tipo de problema é usar Application Performance Monitoring, ou monitoramento de performance de aplicações, geralmente caríssimas, para entregar a resposta que você quer.

Mas o assunto não é este hoje; a ideia é tentar usar o cURL para identificar certos problemas de maneira mais ágil.

curl custom output

Você certamente está acostumado a usar cURL para testar conectividade com um site:

# Qual a versão do kubectl mais nova?
$ curl -L -s https://dl.k8s.io/release/stable.txt
v1.29.0
Enter fullscreen mode Exit fullscreen mode

Ou ainda baixar um programa:

# Vamos baixar o kubectl!
$ 
$ curl -LO "https://dl.k8s.io/release/$LATEST/bin/linux/amd64/kubectl"
...

$ ls -l kubectl
-rw-r--r-- 1 marcelo marcelo 49704960 Dec 19 20:30 kubectl
Enter fullscreen mode Exit fullscreen mode

Mas é possível customizar a saída com diversas coisas. A que mais uso é, de longe, a resposta HTTP:

$ curl www.google.com -so /dev/null -w '%{http_code}\n'
200
Enter fullscreen mode Exit fullscreen mode

Uma maneira extremamente ineficiente de testar se uma aplicação está com problemas é disparar uma rajada de curl sobre ela e analisar a saída:

$ for i in {1..100} ; do 
  curl -so /dev/null 127.0.0.1 -w '%{http_code}\n' ;
done | sort | uniq -c
     83 200
      3 500
      5 503
      9 504
Enter fullscreen mode Exit fullscreen mode

Como eu falei, é uma maneira extremamente ineficiente - você se daria melhor executando testes com uma ferramenta de verdade. Mas quando você está on-call com notebook e te acionam...

Este link tem as variáveis que podem ser usadas juntamente com o programa --write-out.

Variáveis de writeout para exibir tempos

Suponha que você queira saber quanto tempo um download demora, muita gente gosta de usar o comando time:

$ LATEST="$( curl -L -s https://dl.k8s.io/release/stable.txt )"
$ time curl -sLO "https://dl.k8s.io/release/$LATEST/bin/linux/amd64/kubectl"

real    0m0.523s
user    0m0.132s
sys     0m0.141s
Enter fullscreen mode Exit fullscreen mode

Mas a melhor maneira é pedir para o próprio cURL trazer esta métrica!

$ LATEST="$( curl -L -s https://dl.k8s.io/release/stable.txt )"
$ curl -sLO  -w '%{time_total}\n' \
"https://dl.k8s.io/release/$LATEST/bin/linux/amd64/kubectl"
0.441882
Enter fullscreen mode Exit fullscreen mode

A parte interessante é que existem muitas variáveis diferentes de tempo para usar, o que pode ser um excelente recurso na depuração de certos problemas!

Este blog teve a ideia legal de criar um arquivo com o seguinte formato:

$ cat > curl-format.txt << EOF
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_pretransfer: %{time_pretransfer}\n
time_redirect: %{time_redirect}\n
time_starttransfer: %{time_starttransfer}\n
———\n
time_total: %{time_total}\n
EOF
Enter fullscreen mode Exit fullscreen mode

E agora podemos passar este arquivo para o cURL:

$ curl -w "@curl-format.txt" -o /dev/null -s http://devsres.com

time_namelookup: 0.000964
time_connect: 0.002114
time_appconnect: 0.000000
time_pretransfer: 0.002148
time_redirect: 0.000000
time_starttransfer: 0.010617
———
time_total: 0.010684
Enter fullscreen mode Exit fullscreen mode

Genial, não é?

Bem, para achar genial, você precisa saber para que serve cada etapa e como usá-las em diagnóstico.

Vou usar o primeiro, time_namelookup apenas como exemplo!

time_namelookup

O poder de diagnóstico desta diretiva não pode ser mensurado!

Problemas de DNS tendem a ser de difícil diagnóstico para pessoas sem background de redes. Mas observe o seguinte teste em uma máquina que está "consistentemente lenta":

$ curl -w "@curl-format.txt" -o /dev/null -s http://devsres.com
time_namelookup: 5.139453
time_connect: 5.156280
time_appconnect: 0.000000
time_pretransfer: 5.156360
time_redirect: 0.000000
time_starttransfer: 5.172965
———
time_total: 5.173074
Enter fullscreen mode Exit fullscreen mode

Apenas para referência, estes são os tempos esperados em um dia normal:

$ curl -w "@curl-format.txt" -o /dev/null -s http://devsres.com
time_namelookup: 0.046703
time_connect: 0.047609
time_appconnect: 0.000000
time_pretransfer: 0.047647
time_redirect: 0.000000
time_starttransfer: 0.050434
———
time_total: 0.050491
Enter fullscreen mode Exit fullscreen mode

Sabe porque o primeiro teste levou mais de 5 segundos? Porque esse é o tempo padrão que o linux resolver espera para testar a resolução usando o seu servidor secundário!

(man resolv.conf)
timeout:n

Sets the amount of time the resolver will wait for a response from a remote name server before retrying the query via a different name server. This may not be the total time taken by any resolver API call and there is no guarantee that a single resolver API call maps to a single timeout. Measured in seconds, the default is RES_TIMEOUT (currently 5, see ). The value for this option is silently capped to 30.

Configurar múltiplos servidores DNS no seu /etc/resolv.conf é útil para garantir resiliência, mas o ambiente ficará severamente degradado caso o primeiro servidor falhe se precisar resolver nomes para seu funcionamento!

É possível reduzir esse tempo de timeout com a seguinte diretiva em seu resolv.conf:

$ cat /etc/resolv.conf
options timeout:1
nameserver 192.168.0.53
nameserver 1.1.1.1
nameserver 8.8.8.8
Enter fullscreen mode Exit fullscreen mode

A configuração entra em vigor imediatamente:

$ curl -w "@curl-format.txt" -o /dev/null -s http://devsres.com
time_namelookup: 1.115452
time_connect: 1.135235
time_appconnect: 0.000000
time_pretransfer: 1.135265
time_redirect: 0.000000
time_starttransfer: 1.151118
———
time_total: 1.151194
Enter fullscreen mode Exit fullscreen mode

Se não funcionar, talvez seja necessário ajudar esse parâmetro usando network manager.

Neste caso, usamos este parâmetro para permitir identificar que a causa do problema é o não funcionamento do servidor DNS do cliente, e não a aplicação! É um excelente primeiro teste a fazer para identificar se realmente há um problema no seu ambiente, antes de fazer dezenas de verificações e constatar que está tudo ok!

Top comments (0)