Leer e interpretar los logs del servidor Linux
Dedicados & VPS
25

Por qué los logs importan

Cuando algo falla en un servidor, los logs son el primer lugar donde mirar. Cada servicio deja rastro de lo que hace: a qué hora arrancó, qué peticiones recibió, qué errores tuvo, qué usuarios se conectaron. Saber dónde están y cómo leerlos es una habilidad fundamental para administrar un servidor.

Ubicaciones comunes

Logs del sistema

  • /var/log/syslog (Debian/Ubuntu) — eventos generales del sistema.
  • /var/log/messages (CentOS/Rocky) — equivalente.
  • /var/log/kern.log — kernel.
  • /var/log/dmesg — mensajes del kernel al arranque.
  • /var/log/auth.log o /var/log/secure — autenticación (logins SSH, sudo, etc.).
  • /var/log/boot.log — proceso de arranque.

Servidor web Apache

  • /var/log/apache2/access.log — todas las peticiones HTTP.
  • /var/log/apache2/error.log — errores del servidor.
  • En CentOS: /var/log/httpd/access_log y /var/log/httpd/error_log.

Servidor web Nginx

  • /var/log/nginx/access.log
  • /var/log/nginx/error.log

PHP-FPM

  • /var/log/php8.2-fpm.log (ajusta la versión)

MySQL / MariaDB

  • /var/log/mysql/error.log — errores de arranque, crashes, warnings.
  • /var/log/mysql/slow.log — queries lentas (si está habilitado).

Correo (Postfix / Exim / Dovecot)

  • /var/log/mail.log o /var/log/maillog
  • /var/log/dovecot.log

Comandos para trabajar con logs

Leer en tiempo real

tail -f /var/log/nginx/access.log

El clásico. Abre el log y sigue mostrando líneas nuevas conforme llegan. Ideal para diagnosticar un problema reproducible — abres el log en una terminal, reproduces el error en otra, y ves qué aparece.

Últimas N líneas

tail -100 /var/log/syslog

Buscar un patrón

grep "error" /var/log/nginx/error.log
grep -i "warning" /var/log/syslog              # insensible a mayúsculas
grep "404" /var/log/nginx/access.log | wc -l   # contar 404s del día

Combinaciones útiles con pipes

# Últimos 500 errores únicos
tail -5000 /var/log/nginx/error.log | grep "error" | sort -u

# IPs que más peticiones hacen
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

# URLs más visitadas
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

# Códigos de respuesta agrupados
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

systemd journal

En sistemas modernos (Debian 9+, Ubuntu 16+, CentOS 7+), muchos servicios no escriben a archivos planos sino al journal de systemd. Se consulta con journalctl:

Todos los logs

journalctl

Logs de un servicio específico

journalctl -u nginx
journalctl -u mariadb
journalctl -u php8.2-fpm

En tiempo real

journalctl -u nginx -f

Desde cierta fecha

journalctl --since "2026-04-15 00:00" --until "2026-04-15 12:00"
journalctl --since today
journalctl --since "1 hour ago"

Con filtros de prioridad

journalctl -p err                # solo errores
journalctl -p warning..err       # warnings y errores

Entendiendo el formato de access.log

Un log de acceso típico (Nginx/Apache) tiene el formato:

192.0.2.10 - - [15/Apr/2026:10:23:45 +0000] "GET /producto/123 HTTP/1.1" 200 4521 "https://google.com" "Mozilla/5.0..."

Campo por campo:

  • 192.0.2.10 — IP del visitante.
  • - - — identificadores obsoletos, suelen estar vacíos.
  • [15/Apr/2026:10:23:45 +0000] — fecha y hora.
  • "GET /producto/123 HTTP/1.1" — método, ruta y versión HTTP.
  • 200 — código de respuesta (200 OK, 404 Not Found, 500 Error...).
  • 4521 — bytes enviados al cliente.
  • "https://google.com" — referrer (desde dónde llegó).
  • "Mozilla/5.0..." — user agent (navegador o bot).

Códigos HTTP más importantes

  • 2xx — éxito. 200 OK, 201 Created, 204 No Content.
  • 3xx — redirecciones. 301 (permanente), 302 (temporal), 304 (no modificado — caché).
  • 4xx — error del cliente. 400 malformada, 401 sin auth, 403 prohibido, 404 no existe.
  • 5xx — error del servidor. 500 error genérico, 502 bad gateway, 503 sin disponibilidad, 504 timeout.

Muchos 404s suelen ser bots escaneando. Muchos 500s indican problema real — revisa el error.log inmediatamente.

Diagnóstico rápido de problemas comunes

Sitio caído ("502 Bad Gateway")

  1. tail -20 /var/log/nginx/error.log — busca "connect() failed" o "upstream timed out".
  2. systemctl status php8.2-fpm — verifica que PHP-FPM está corriendo.
  3. tail -50 /var/log/php8.2-fpm.log — errores del proceso PHP.

MySQL no arranca

  1. tail -50 /var/log/mysql/error.log — casi siempre el error exacto está aquí.
  2. Revisa causas típicas: disco lleno (df -h), my.cnf mal editado, permisos de /var/lib/mysql.

Muchos intentos de login fallido (SSH)

grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn

Lista las IPs con más intentos fallidos. Si hay volúmenes altos, configura fail2ban o bloquéalas en el firewall.

Sitio lento de repente

  1. Revisa carga del sistema: uptime, htop.
  2. Busca picos en access.log: tail -1000 access.log | awk '{print $4}' | sort | uniq -c.
  3. Revisa queries lentas: tail -100 /var/log/mysql/slow.log.

Rotación de logs con logrotate

Los logs crecen indefinidamente si no se rotan. logrotate ya viene configurado en la mayoría de distribuciones para los servicios comunes. Revisa su configuración en:

/etc/logrotate.d/

Cada archivo es para un servicio. Un ejemplo típico:

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] && kill -USR1 $(cat /var/run/nginx.pid)
    endscript
}

Qué hace: rota diariamente, guarda 14 versiones, comprime las antiguas, recarga Nginx tras rotar. Si tu log favorito no rota y crece sin límite, añádele un archivo similar en /etc/logrotate.d/.