Hosting Equipo Avantys 7 min

Logs en VPS: Guía de Análisis y Gestión

Domina los logs de tu VPS. Ubicaciones, comandos esenciales, rotación, análisis de errores y centralización con herramientas modernas.

// Compartir

Logs en VPS: Guía de Análisis y Gestión
Logs en VPS - análisis y gestión

Los logs son la caja negra de tu servidor. Cuando algo falla, los logs tienen la respuesta. Pero si no sabes dónde buscar ni cómo interpretarlos, son inútiles.

Esta guía te enseña a dominar los logs de tu VPS.

Ubicaciones de logs importantes

Ubicaciones de logs en VPS

Logs del sistema

ArchivoContenido
/var/log/syslogMensajes generales del sistema
/var/log/auth.logAutenticación, SSH, sudo
/var/log/kern.logMensajes del kernel
/var/log/dmesgArranque y hardware
/var/log/faillogIntentos de login fallidos

Logs de servicios web

ArchivoContenido
/var/log/nginx/access.logPeticiones a Nginx
/var/log/nginx/error.logErrores de Nginx
/var/log/apache2/access.logPeticiones a Apache
/var/log/apache2/error.logErrores de Apache

Logs de aplicaciones

ArchivoContenido
/var/log/mysql/error.logErrores de MySQL
/var/log/php8.2-fpm.logErrores de PHP-FPM
/var/log/redis/redis-server.logLogs de Redis
/var/log/postgresql/Logs de PostgreSQL

Logs de seguridad

ArchivoContenido
/var/log/auth.logSSH, sudo, login
/var/log/fail2ban.logBans de Fail2Ban
/var/log/ufw.logFirewall UFW

Comandos esenciales

Comandos para logs en VPS

Ver logs en tiempo real

# Seguir un archivo
tail -f /var/log/syslog

# Seguir múltiples archivos
tail -f /var/log/nginx/*.log

# Con colores (requiere ccze)
tail -f /var/log/syslog | ccze -A

Buscar en logs

# Buscar texto
grep "error" /var/log/syslog

# Ignorar mayúsculas/minúsculas
grep -i "error" /var/log/syslog

# Con contexto (3 líneas antes y después)
grep -C 3 "error" /var/log/syslog

# Buscar en múltiples archivos
grep -r "error" /var/log/nginx/

# Invertir búsqueda (excluir)
grep -v "GET /health" /var/log/nginx/access.log

Filtrar por fecha

# Logs de hoy
grep "$(date '+%b %d')" /var/log/syslog

# Logs de ayer
grep "$(date -d 'yesterday' '+%b %d')" /var/log/syslog

# Rango de tiempo con awk
awk '/Feb  9 10:00/,/Feb  9 11:00/' /var/log/syslog

Contar ocurrencias

# Contar errores
grep -c "error" /var/log/syslog

# Top 10 IPs en access.log
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

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

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

Journalctl: El poder de systemd

Comandos básicos

# Ver todos los logs
journalctl

# Logs del sistema actual (desde último boot)
journalctl -b

# Logs del boot anterior
journalctl -b -1

# Seguir en tiempo real
journalctl -f

Filtrar por servicio

# Logs de Nginx
journalctl -u nginx

# Logs de MySQL
journalctl -u mysql

# Logs de PHP-FPM
journalctl -u php8.2-fpm

# Múltiples servicios
journalctl -u nginx -u php8.2-fpm

Filtrar por prioridad

# Solo errores y superiores
journalctl -p err

# Solo críticos
journalctl -p crit

# Niveles: emerg, alert, crit, err, warning, notice, info, debug
journalctl -p warning

Filtrar por tiempo

# Última hora
journalctl --since "1 hour ago"

# Hoy
journalctl --since today

# Ayer
journalctl --since yesterday --until today

# Rango específico
journalctl --since "2026-02-09 10:00" --until "2026-02-09 12:00"

# Últimos 100 mensajes
journalctl -n 100

Formato de salida

# Sin paginador
journalctl --no-pager

# JSON (para procesar)
journalctl -o json

# JSON legible
journalctl -o json-pretty

# Solo mensajes (sin metadata)
journalctl -o cat

Análisis de logs de Nginx

Access log formato

IP - - [fecha] "método URL protocolo" código tamaño "referer" "user-agent"

Análisis útiles

# Peticiones por código de respuesta
awk '{print $9}' access.log | sort | uniq -c | sort -rn

# 404s (páginas no encontradas)
grep '" 404 ' access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20

# 500s (errores de servidor)
grep '" 500 ' access.log | tail -20

# Peticiones por hora
awk '{print $4}' access.log | cut -d: -f1,2 | uniq -c

# Ancho de banda por IP
awk '{sum[$1] += $10} END {for (ip in sum) print sum[ip], ip}' access.log | sort -rn | head -10

# Bots y crawlers
grep -i "bot\|crawler\|spider" access.log | awk '{print $1}' | sort | uniq -c | sort -rn

Detectar ataques

# IPs con más de 1000 peticiones
awk '{print $1}' access.log | sort | uniq -c | sort -rn | awk '$1 > 1000'

# Intentos de acceso a archivos sospechosos
grep -E "\.(php|asp|aspx|jsp|cgi)$" access.log | grep -v "index.php"

# Intentos de SQL injection
grep -E "(select|union|insert|delete|update|drop)" access.log

# Intentos de path traversal
grep "\.\.\/" access.log

Análisis de logs de errores

Nginx error.log

# Últimos errores
tail -50 /var/log/nginx/error.log

# Errores críticos
grep -E "\[crit\]|\[emerg\]|\[alert\]" /var/log/nginx/error.log

# Errores de upstream (PHP-FPM)
grep "upstream" /var/log/nginx/error.log

# Conexiones rechazadas
grep "Connection refused" /var/log/nginx/error.log

PHP-FPM logs

# Errores de PHP
grep -E "Fatal|Error|Warning" /var/log/php8.2-fpm.log

# Slow requests (si está habilitado)
grep "slow" /var/log/php8.2-fpm.log

# Pool errors
grep "pool" /var/log/php8.2-fpm.log

MySQL error.log

# Errores recientes
tail -100 /var/log/mysql/error.log

# Queries abortadas
grep "Aborted" /var/log/mysql/error.log

# Errores de conexión
grep -i "connection" /var/log/mysql/error.log

# Warnings
grep "Warning" /var/log/mysql/error.log

Rotación de logs con logrotate

Configuración por defecto

# Configuración global
cat /etc/logrotate.conf

# Configuraciones específicas
ls /etc/logrotate.d/

Configuración personalizada

# /etc/logrotate.d/mi-app
/var/www/mi-app/logs/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data www-data
    sharedscripts
    postrotate
        systemctl reload nginx > /dev/null 2>&1 || true
    endscript
}

Opciones comunes

OpciónSignificado
daily/weekly/monthlyFrecuencia de rotación
rotate 7Mantener 7 archivos
compressComprimir logs antiguos
delaycompressComprimir en la siguiente rotación
missingokNo error si falta el archivo
notifemptyNo rotar si está vacío
copytruncateCopiar y truncar (para apps que no reabren)

Probar configuración

# Probar sin ejecutar
logrotate -d /etc/logrotate.d/mi-app

# Forzar rotación
logrotate -f /etc/logrotate.d/mi-app

Scripts de análisis útiles

Resumen diario de logs

#!/bin/bash
# /root/scripts/daily-log-report.sh

echo "========== RESUMEN DE LOGS $(date '+%Y-%m-%d') =========="
echo ""

echo "=== ERRORES DEL SISTEMA ==="
journalctl -p err --since yesterday --until today --no-pager | tail -20
echo ""

echo "=== TOP 10 IPs (Nginx) ==="
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
echo ""

echo "=== CÓDIGOS DE RESPUESTA ==="
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
echo ""

echo "=== INTENTOS SSH FALLIDOS ==="
grep "Failed password" /var/log/auth.log | wc -l
echo ""

echo "=== BANS DE FAIL2BAN ==="
grep "Ban" /var/log/fail2ban.log | tail -10
echo ""

echo "=== ESPACIO EN LOGS ==="
du -sh /var/log/*/ 2>/dev/null | sort -rh | head -10

Monitor de errores en tiempo real

#!/bin/bash
# /root/scripts/error-monitor.sh

# Monitorear múltiples logs por errores
tail -f /var/log/nginx/error.log \
        /var/log/php8.2-fpm.log \
        /var/log/mysql/error.log 2>/dev/null | \
    grep --line-buffered -i "error\|fatal\|crit"

Alerta por errores excesivos

#!/bin/bash
# /root/scripts/check-errors.sh

THRESHOLD=50
ERRORS=$(journalctl -p err --since "5 minutes ago" --no-pager | wc -l)

if [ $ERRORS -gt $THRESHOLD ]; then
    echo "$ERRORS errores en los últimos 5 minutos" | \
        mail -s "ALERTA: Errores excesivos en VPS" [email protected]
fi

Centralización de logs

Enviar logs a servidor remoto

# /etc/rsyslog.d/remote.conf
*.* @logserver.tudominio.com:514   # UDP
*.* @@logserver.tudominio.com:514  # TCP

# Reiniciar
systemctl restart rsyslog

Loki + Grafana (Docker)

# docker-compose.yml
version: '3.8'

services:
  loki:
    image: grafana/loki:latest
    ports:
      - "3100:3100"
    volumes:
      - loki-data:/loki

  promtail:
    image: grafana/promtail:latest
    volumes:
      - /var/log:/var/log:ro
      - ./promtail-config.yml:/etc/promtail/config.yml
    command: -config.file=/etc/promtail/config.yml

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana

volumes:
  loki-data:
  grafana-data:

Limpieza de logs

Limpiar manualmente

# Vaciar log sin eliminar archivo
> /var/log/nginx/access.log

# Truncar a últimas 1000 líneas
tail -1000 /var/log/syslog > /var/log/syslog.tmp && mv /var/log/syslog.tmp /var/log/syslog

# Eliminar logs antiguos de journald
journalctl --vacuum-time=7d    # Mantener 7 días
journalctl --vacuum-size=500M  # Mantener 500MB

Configurar límite de journald

# /etc/systemd/journald.conf
[Journal]
SystemMaxUse=500M
SystemMaxFileSize=50M
MaxRetentionSec=1week
systemctl restart systemd-journald

Preguntas frecuentes

¿Dónde están los logs si mi aplicación falla?

Empieza con journalctl -u nombre-servicio para servicios systemd. Para apps web, revisa /var/log/nginx/error.log o el log específico de tu framework.

¿Cuánto espacio deben ocupar los logs?

Depende del tráfico, pero típicamente 500MB-2GB es razonable. Si ocupan más, configura mejor logrotate o reduce el nivel de logging.

¿Cómo encuentro quién está atacando mi servidor?

Revisa /var/log/auth.log para SSH y /var/log/nginx/access.log para web. Busca IPs con muchas peticiones o intentos fallidos.

¿Debo mantener logs antiguos?

Para cumplimiento legal o debugging, mantén 30-90 días. Comprímelos con logrotate. Archiva logs críticos en almacenamiento externo.

¿journalctl o archivos de log tradicionales?

journalctl para servicios systemd y logs del sistema. Archivos tradicionales para apps específicas. Ambos tienen su uso.

Nuestra recomendación

Para el día a día:

  • journalctl -f para logs en tiempo real
  • grep para buscar errores específicos
  • Script de resumen diario

Para producción:

  • Logrotate bien configurado
  • Alertas por errores excesivos
  • Centralización si tienes múltiples VPS

¿Necesitas gestión profesional de logs? La administración gestionada de Avantys incluye análisis y alertas de logs.


Conclusión

Los logs son tu mejor amigo cuando algo falla. Domina journalctl, configura rotación adecuada, y crea scripts de análisis que te ahorren tiempo.

No esperes a tener un problema para aprender a leer logs.

¿Necesitas un VPS con logging avanzado? Explora los VPS de Avantys con monitorización incluida.


¿Quieres que lo hagamos por ti?

En Avantys gestionamos tu web, hosting y crecimiento digital de punta a punta. Tú a lo importante.

Hablar con Avantys
// Boletín

Suscríbete al boletín

Guías nuevas, sin spam. Cancela cuando quieras.