Cristian Spinetta
@cebspinetta
@cspinetta
Ver algunas herramientas de sistema para diagnosticar problemas en prod
Desmitificar el uso de las mismas
Practicar con casos reales de nuestro ámbito laboral
Volver a lo básico sobre como funcionan las cosas
Es lo más fiable
Lo tenes disponible casi siempre
Ir al código fuente no siempre es una opción
Porque no siempre podes usar las tools de tu laptop
Al incorporarlas, ganas velocidad para aislar/detectar problemas
Además, a veces es tarde y no hay tiempo para contactar al que podría conocer la causa. Solo queres aislar el problema y volver a la cama!
Problemas entre apps
Problemas en uso de recursos
Problemas a nivel proceso
Repaso rápido de redes
Transmission Control Protocol
Paquete:
Flags:
Transmission Control Protocol
Abrir conexión:
Cerrar conexión:
Hypertext Transfer Protocol
Headers útiles:
- X-Forwarded-For (quién realmente me está llamando)
- X-UOW (unit-of-work, ID de correlación sobre la red)
- X-Request-Id (id de la req a nivel instancia - a.k.a. span)
- X-Client (app que está haciendo la request)
- User-Agent (identificación de app/sistema/versión y más)
Estoy recibiendo requests? Cómo son?
Qué requests está generando mi app?
Que le responden exactamente?
Cuántas conexiones tengo abiertas?
Puedo conectarme a un host?
Que diferencia hay entre la request que hago y la que hace mi app?
Cuanto duran las conexiones?
entre otras...
ifconfig
muestra status de cada interface
ip addr
IP asignada a cada interface
Ejemplo:
Unknown host: el hostname no se puede traducirse a una IP.
Ping!
Ping checkea si se puede alcanzar un host remoto
> ping remote-app
Además imprime estadística y a que IP resuelve
Posibles errores:
Network unreachable: no se puede rutear los paquetes a destino.
No answer: el host remoto fue alcanzado, pero no responde.
Y con traceroute podes ver que camino toma para alcanzarlo!
Ejemplo:
Telnet
> telnet remote-app 9290
Abre una conexión TCP contra un socket especificado
Ejemplo:
Netcat
> nc -vz remote-app 9290
Abre una conexión TCP contra un socket especificado y la vuelve a cerrar
-v info extra
-z Zero-I/O - solo reportar estado de la con.
Netstat
> netstat -nap
Muestra todas las conexiones actuales, mostrando el proceso asociado
-a, --all muestra todos los sockets.
-n, --numeric muestra direcciones numéricas en general (IP, nro. de puerto, etc).
-p, --program muestra pid y nombre del proceso asociado.
-l, --listening muestra solo sockets en modo "listening".
-t, --tcp muestra solo sockets TCP.
-u, --udp muestra solo sockets UDP.
-x, --unix muestra solo sockets Unix.
Está siendo reemplazado por ss e ip
-n mostrar las direcciones en número.
-a mostrar todos los sockets.
-p mostrar el proceso que lo usa.
-c, --continuous imprimir resultados cada 1 segundo.
Algunos suelen escribir:
> netstat -putona
-o, --timers tiempos de red
> watch -n 0.1 "netstat -nap | grep -E 'java|Send'"
Ver conexiones en vivo:
nslookup
> nslookup 10.172.13.216
tool para hacer queries a los DNS.
netstat dice que tengo una conexión abierta a la IP 10.172.13.216:
¿Cómo averiguo a que server pertenece esa IP?
dig
> dig -x 10.172.13.216 +short
Otra tool para hacer queries a los DNS.
-x "reverse lookup"
+short respuesta concisa.
host
> host 10.172.13.216
Otra tool para hacer queries a DNS.
Cada una tiene distintas opciones y flexibilidades
A veces los DNS no tienen el mapeo inverso de IP -> Nombre
Ejemplo:
Mi app está levantada en el 9290, ¿está recibiendo tráfico?
TcpDump!
https://www.tcpdump.org/ | TcpDump Zine by Julia Evans
Esta tool captura el tráfico que pasa por la red
> tcpdump -i any "port 9290"
-i en que interfaces escuchar
Que está recibiendo exactamente por el 9290?
> tcpdump -i any -A "port 9290"
-i en que interfaces escuchar
-A imprimir el contenido del paquete en ASCII
Flags:
S | SYNC sincronizar seq. (solo para abrir conexión)
F | FIN el sender finaliza el envío de datos.
R | Reset reiniciar conexión.
P | Push disponibilizar pronto los datos al proceso receptor.
. ninguno de los flags anteriores.
Opciones más usadas:
-A imprimir cada paquete en ASCII.
-n, --numeric muestra direcciones numéricas en general (IP, nro. de puerto, etc).
-i {interface} para especificar en que interface queres escuchar. ("any" para todas)
-c {count} cantidad máxima de paquetes a capturar.
-w {file} guardar en un archivo en formato pcap.
-C {file_size} rotar el archivo por tamaño.
-G {rotate_seconds} rotar el archivo por tiempo.
Formato:
Muy útil para luego abrirlo en Wireshark!
-s {packet_length} cuantos bytes tomar del paquete.
Útil si solo te interesa analizar algo del header.
-r {file} leer un archivo pcap.
BPF: https://biot.com/capstats/bpf.html
Generador de filtro por String: https://www.wireshark.org/tools/string-cf.html
Filtros más usadas:
Desde o hasta el host 1.2.3.4
Formato:
tcpdump -i any -A "host 1.2.3.4"
Paquetes hacia el host 1.2.3.4
tcpdump -i any -A "dst host 1.2.3.4"
Paquetes desde el puerto 8080
tcpdump -i any -A "src port 8080"
Paquetes hacia el host 1.2.3.4 y desde el puerto 80 o desde el puerto 443
tcpdump -i any -A "dst host 192.168.1.1 and (dst port 80 or dst port 443)"
Solo paquetes relacionados con abrir o cerrar conexión
tcpdump -n "tcp[tcpflags] & (tcp-syn|tcp-fin) != 0"
Requests y responses hacia los DNS
tcpdump -n "port 53"
Que requests tengo desde la IP 1.2.3.4?
> tcpdump -i any -A "host 1.2.3.4"
Que requests estoy recibiendo con el header "X-UOW: learning-tcpdump"?
> tcpdump -i any -A "port 9290" | grep -C 50 'learning-tcpdump'
Que server me está rechazando la conexión? (connection refused / connection reset)
> tcpdump -i any 'tcp[tcpflags] & tcp-rst != 0'
Cuánto duran las conexiones a la base? (1.2.3.4:3306)
> tcpdump -i any -w db-connections.pcap "host 1.2.3.4 and port 3306"
y luego abro el archivo db-connections.pcap con Wireshark
Ejemplos:
Cómo se está usando el CPU? en exceso? está ocioso?
Está saturado?
La memoria? la red?
Uso de disco intenso? Hay swap?
Extraído de este post: https://codeahoy.com/2017/01/20/hhtop-explained-visually/
uptime
uptime
Cuanto hace que el sistema está UP y el uso de CPU de los últimos 1', 5' y 15''
ps
ps -e -o pid,ppid,%cpu,%mem,cmd --sort -%cpu | head -5
TOP5 de procesos con más uso de CPU
Da un pantallazo de la evolución del sistema
free
free -h
Muestra uso de memoria principal
shared memoria usada por el tmpfs (memoria compartida)
cache Virtual Page Cache.
buffers bloques de disco (metadata de los archivos).
-/+ buffers/cache muestra used y free desde la visión de un proceso.
df
df -h
Uso de disco de los file systems
du
du -sh
Tamaño ocupado por archivos/directorios
iostat
iostat [options] [interval [count]]
Guarda stats desde la última ejecución
Algunas columnas:
r/s read requests por segundo
w/s write requests por segundo
rMB/s sectores leídos por segundo (en MB)
wMB/s sectores escritos por segundo (en MB)
%util % de tiempo dedicado a la operación de I/O
Muy útil para ver cuanto tiempo se pierde por I/O
nicstat
nicstat [options] [interval [count]]
Guarda stats desde la última ejecución
Algunas columnas:
rAvs tamaño promedio de paquetes leídos
wAvs tamaño promedio de paquetes escritos
%util % de tiempo dedicado a la operación de I/O
Sat Saturación de la interface (error/sec)
Muy útil para ver cuanto tiempo se pierde por network
muestra info de los procesos que están corriendo
Info general de los procesos relevantes
ps -fea
cmd line
ps -ww -eo pid,cmd
CPU / mem / rss / cmd line
ps -ww -ae -o pid,%cpu,%mem,rss,cmd --sort -%cpu
TOP10 de uso de CPU
ps -ae -o pid,%cpu,%mem,rss,cmd --sort -%cpu | head -10
ps
Opciones más usadas:
-a todos los procesos (menos de sesión o no asociado a terminal)
-e todos los procesos
-ww no truncar la linea
-f columnas predeterminadas de salida (pid, ppid, tiempos, ...)
-o {col_1,col_2,...,col_n} personalizar columnas
--forest mostrar jerarquía de procesos en forma de árbol
-p {pid} seleccionar un proceso
L listar todas las columnas posibles
Lo mismo, pero para un pid específico
ps -ww -p {pid} -o pid,%cpu,%mem,rss,cmd
monitorea uso general de recursos de un proceso
-m Memoria y Page faults
pidstat -r -p {pid} 1
-d I/O
pidstat -d -p {pid} 1
-u CPU
pidstat -u -p {pid} 1
-v threads y file descriptors
pidstat -v -p {pid} 1
pidstat
-w context switchs (voluntarios y no voluntarios) / seg
pidstat -w -p {pid} 1
Opciones útiles
-t info por thread
-l imprimir command con argumentos
-e {command} ejecutar command y monitorear
-C {command filter} mostrar stats solo para los comandos que coincidan con el filtro
-T [TASK|CHILD|ALL]
# TASK = solo la tarea
# CHILD = global para tarea+children
# ALL = para children + global
permite observar los archivos abiertos por un proceso
lsof
Procesos que tienen abierto el archivo [path/to/file]
lsof [path/to/file]
Procesos que abrieron algún archivo bajo la carpeta [/path/to/folder]
lsof +D [path/to/folder]
Listar archivos abiertos por el proceso [pid]
lsof -p [pid]
Listar archivos de conexiones
lsof -i
Listar todos los archivos de conexión abierto por el proceso [pid]
lsof -i -a -p [pid]
-a es necesario para encadenar con AND operator varios filtros
Listar las conexiones relacionadas al puerto 8080
lsof -i :8080
Munin
Métricas de sistema con histórico de varios meses
NetData
Métricas de sistema en realtime con histórico de 1 hora apróx.
Cuando entras a una instancia, aparece la URL para acceder:
PerfDB
Tool interna de Despegar, que almacena y expone dashboards con métricas de acceso a las API
Se genera un métrica por servicio, que se puede customizar agregando el header X-Service: transaction-name
Cualquier persona con usuario en Despegar, puede ver las métricas de cualquier app. Es muy útil en momentos de guardia y troubleshooting.
¿quienes son los clientes del cluster?
Tiempos por endpoint
Throughput por status code
Cantidad de bytes transferidos en requests y responses
Permite responder:
Error rate
Las métricas se toman desde los balancers
¿Algún mensaje del sistema?
dmesg | tail -50
¿quién está usando el CPU?
pidstat 1
¿que conexiones tengo?
watch -n 0.1 "netstat -nap | grep java"
¿hay espacio en disco?
df -h
¿como está la RAM?
free -mh
¿Mucho uso de disco?
iostat -dx 1
¿Qué estoy recibiendo por el 9290?
tcpdump -i any -A "port 9290"
Blog de Brendan Gregg
Blog de Julia Evans
TCP/IP illustrated Vol.1, por W. Richard stevens
Libros:
The Linux Programming Interface por michael kerrisk
Systems Performance: Enterprise and the Cloud por Brendan Gregg
Links:
Linux Perf analysis in 60''
Netflix at Velocity 2015: Linux Performance Tools
¡ Muchas Gracias !
Cristian Spinetta | @c_spinetta
Bonus!
mpstat
mpstat [interval [count]]
Multi-processor stats
%usr tiempo de CPU ejecutando user-code
%nice tiempo de CPU ejecutando user-code con nice-priority (baja prioridad)
%sys tiempo de CPU en ejecución de kernel-code
%iowait tiempo de CPU esperando I/O
%irq tiempo de CPU atendiendo interrupciones de hardware
%soft tiempo de CPU atendiendo interrupciones de software
%steal tiempo tomado por el hypervisor de las vms
%guest tiempo tomado por un proceso de otra vm
%gnice tiempo de CPU tomado por un proceso niced de otra vm
%idle tiempo de CPU idle
mpstat -P ALL
Métricas desagregadas por core
Útil para buscar desbalanceo de carga
vmstat
vmstat [interval [count]]
Guarda stats desde la última ejecución
La 1er línea se descarta, ya que muestra datos desde el boot
(Virtual Memory stats)
Columnas relacionadas con CPU:
r procesos listos para ejecutar
b procesos ininterrumpidamente en sleep
us tiempo de CPU en ejecución de código de usuario
sy tiempo de CPU en ejecución de código kernel
id tiempo de CPU idle
wa tiempo de CPU esperando I/O (antes a Linux 2.5.41, estaba incluido en id)
st tiempo de CPU robado por otra virtual (existe a partir de Linux 2.6.11)
Si es mayor a la cantidad de cores, podría haber saturación
tracea las invocaciones de syscalls e interrupciones de un proceso
Detallar cada syscall de {command}
strace {command}
Detallar cada syscall de {pid}
strace -p {pid}
Detallar cada syscall de {pid} y sus threads/procesos hijos
strace -fp {pid}
strace
Filtros:
-e expression
-e trace=[set|syscall_name]
donde set puede ser un grupo de syscall (listado en el man)
-e status=[successfully|failed|...]
-e write=[file descriptors separados por coma]
-e read=[file descriptors separados por coma]
OJO!!
Genera un overhead muy grande. El uso en prod tiene que estar muy justificado.
(básicamente pausa el proceso por cada syscall)
Existen alternativas que generan un overhead mínimo. Por ej, perf_events
strace post by Brendan Gregg: http://www.brendangregg.com/blog/2014-05-11/strace-wow-much-syscall.html
Falta: swapon, sar, perf_events, eBPF