--- title: "Cómo monitorizar servicios con systemd en Ubuntu 24.04" description: "Aprende a vigilar servicios con systemctl, journalctl y systemd-cgtop en Ubuntu 24.04, a reiniciarlos solos cuando fallan y a recibir un aviso con OnFailure." category: "Monitoring Logging" language: es source: https://cubepath.com/es/docs/monitoring-logging/monitoreo-de-servicios-con-systemd updated: 2026-09-25 --- # Cómo monitorizar servicios con systemd en Ubuntu 24.04 systemd no solo arranca y detiene servicios: también sabe en qué estado está cada uno, cuánta CPU y memoria consume, cuántas veces se ha reiniciado y qué ha escrito en el journal. En este tutorial usarás esas capacidades en Ubuntu 24.04 para revisar el estado de un servicio, medir sus recursos, hacer que se reinicie solo cuando falle y recibir un aviso cuando systemd deje de intentarlo. Como ejemplo se usa Nginx, pero todo aplica a cualquier unidad `.service`. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. Los comandos funcionan igual en Debian 12 y Rocky Linux 9, que también usan systemd. - Un usuario no root con privilegios `sudo`. - Nginx instalado como servicio de ejemplo. Si no lo tienes, instálalo con `sudo apt install nginx`. ## Paso 1: Consultar el estado de un servicio El punto de partida es `systemctl status`, que resume en una pantalla el estado, el PID principal, los recursos consumidos y las últimas líneas del log: ```bash systemctl status nginx --no-pager ``` ```output ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled) Active: active (running) since Thu 2026-09-24 10:12:03 UTC; 2h 5min ago Docs: man:nginx(8) Main PID: 1234 (nginx) Tasks: 3 (limit: 2267) Memory: 4.1M (peak: 4.6M) CPU: 52ms CGroup: /system.slice/nginx.service ├─1234 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;" └─1235 "nginx: worker process" ``` Fíjate en tres líneas: - `Loaded` indica si la unidad está habilitada (`enabled`) para arrancar con el sistema. - `Active` muestra el estado: `active (running)` en marcha, `inactive (dead)` detenido, `failed` si terminó con error. - `Tasks`, `Memory` y `CPU` salen de la contabilidad de cgroups que systemd mantiene por servicio. Para scripts y comprobaciones rápidas, usa las variantes `is-*`, que devuelven una sola palabra y un código de salida: ```bash systemctl is-active nginx systemctl is-enabled nginx ``` ```output active enabled ``` Si quieres valores concretos, `systemctl show` con `-p` y `--value` imprime propiedades de la unidad sin formato adicional: ```bash systemctl show nginx -p ActiveState -p SubState -p MainPID -p ActiveEnterTimestamp ``` ```output MainPID=1234 ActiveState=active SubState=running ActiveEnterTimestamp=Thu 2026-09-24 10:12:03 UTC ``` ## Paso 2: Localizar servicios fallidos Un servidor sano no debería tener unidades en estado `failed`. Este comando las lista todas: ```bash systemctl --failed ``` ```output UNIT LOAD ACTIVE SUB DESCRIPTION 0 loaded units listed. ``` Si aparece alguna, `systemctl show` te dice por qué terminó. La propiedad `Result` puede valer `exit-code`, `signal`, `core-dump`, `timeout` o `start-limit-hit`, y `ExecMainStatus` guarda el código de salida del proceso: ```bash systemctl show nombre_del_servicio -p Result -p ExecMainStatus ``` Una vez corregido el problema, limpia el estado de fallo para que la unidad deje de aparecer en la lista: ```bash sudo systemctl reset-failed nombre_del_servicio ``` ## Paso 3: Revisar los logs del servicio con journalctl Todo lo que un servicio escribe en la salida estándar o de error acaba en el journal, etiquetado con su unidad. Filtra por unidad con `-u` y muestra solo las últimas líneas con `-n`: ```bash journalctl -u nginx -n 20 --no-pager ``` Para ver únicamente errores de la última hora, combina `-p err` con `--since`: ```bash journalctl -u nginx -p err --since "1 hour ago" --no-pager ``` ```output -- No entries -- ``` Y para seguir el log en tiempo real mientras reproduces un problema, usa `-f` y pulsa `Ctrl+C` para salir: ```bash journalctl -u nginx -f ``` `journalctl -u` incluye también los mensajes que escribe el propio systemd sobre la unidad, así que puedes ver el historial de arranques, paradas y fallos buscando esas líneas con `-g`: ```bash journalctl -u nginx -g "Started|Stopped|Failed" --no-pager ``` > Nota: la guía de journalctl de esta misma sección explica en detalle los filtros por tiempo, prioridad y arranque, y cómo configurar la retención de logs. ## Paso 4: Medir CPU, memoria y tareas por servicio Ubuntu 24.04 usa cgroups v2 con contabilidad de CPU, memoria y tareas activada por defecto, así que systemd sabe exactamente cuánto consume cada servicio, incluidos todos sus procesos hijos. Para una vista en vivo, similar a `top` pero agrupada por servicio, usa `systemd-cgtop`: ```bash sudo systemd-cgtop ``` Dentro del programa, pulsa `c` para ordenar por CPU, `m` por memoria, `t` por número de tareas y `q` para salir. Si solo quieres una foto puntual, por ejemplo para pegarla en un ticket, usa el modo batch con una iteración: ```bash sudo systemd-cgtop -b -n 1 | head -15 ``` Para un servicio concreto, consulta las propiedades de consumo. `MemoryCurrent` está en bytes y `CPUUsageNSec` en nanosegundos de CPU acumulados desde el último arranque: ```bash systemctl show nginx -p MemoryCurrent -p CPUUsageNSec -p TasksCurrent ``` ```output MemoryCurrent=4308992 CPUUsageNSec=52187000 TasksCurrent=3 ``` Si prefieres la memoria en un formato legible, `numfmt` (incluido en coreutils) hace la conversión: ```bash systemctl show nginx -p MemoryCurrent --value | numfmt --to=iec ``` ```output 4.2M ``` ## Paso 5: Reiniciar el servicio automáticamente cuando falle Por defecto, muchas unidades no se reinician si el proceso muere. La directiva `Restart=on-failure` hace que systemd lo vuelva a arrancar cuando termina con un código distinto de cero, por una señal, por un timeout o por el watchdog, pero no cuando lo paras tú con `systemctl stop`. No edites el archivo del paquete en `/usr/lib/systemd/system/`, porque una actualización lo sobrescribiría. Crea un override con `systemctl edit`, que abre un archivo en `/etc/systemd/system/nginx.service.d/override.conf`: ```bash sudo systemctl edit nginx ``` Añade este bloque en la zona indicada del editor, entre los comentarios: ```ini [Unit] StartLimitIntervalSec=300 StartLimitBurst=5 [Service] Restart=on-failure RestartSec=5s ``` Qué hace cada línea: - `Restart=on-failure`: reinicia el servicio si termina de forma anómala. - `RestartSec=5s`: espera cinco segundos antes de cada reintento, para no entrar en un bucle inmediato. - `StartLimitIntervalSec` y `StartLimitBurst`: si el servicio arranca más de 5 veces en 300 segundos, systemd deja de intentarlo y lo marca como `failed` con el resultado `start-limit-hit`. Estas dos directivas van en la sección `[Unit]`. Guarda y cierra el editor. `systemctl edit` recarga la configuración de systemd al salir, así que puedes comprobar directamente que los valores se han aplicado: ```bash systemctl show nginx -p Restart -p RestartUSec -p StartLimitBurst ``` ```output Restart=on-failure RestartUSec=5s StartLimitBurst=5 ``` ### Probar el reinicio automático Simula un fallo matando el proceso principal con `SIGKILL`, que es lo que ocurriría si el kernel lo terminase por falta de memoria: ```bash sudo kill -9 "$(systemctl show nginx -p MainPID --value)" ``` Espera unos segundos y consulta el contador de reinicios automáticos, `NRestarts`: ```bash sleep 6; systemctl show nginx -p NRestarts -p ActiveState ``` ```output NRestarts=1 ActiveState=active ``` El journal también refleja lo ocurrido: ```bash journalctl -u nginx -n 5 --no-pager ``` ```output Sep 24 12:20:14 web01 systemd[1]: nginx.service: Main process exited, code=killed, status=9/KILL Sep 24 12:20:14 web01 systemd[1]: nginx.service: Failed with result 'signal'. Sep 24 12:20:19 web01 systemd[1]: nginx.service: Scheduled restart job, restart counter is at 1. Sep 24 12:20:19 web01 systemd[1]: Starting nginx.service - A high performance web server and a reverse proxy server... Sep 24 12:20:19 web01 systemd[1]: Started nginx.service - A high performance web server and a reverse proxy server. ``` ## Paso 6: Recibir un aviso con OnFailure Reiniciar solo resuelve fallos puntuales. Si el servicio no consigue arrancar y agota el límite de reintentos, necesitas enterarte. La directiva `OnFailure=` arranca otra unidad cuando la primera entra en estado `failed`. Crearás una unidad plantilla que envía un aviso con el nombre del servicio caído. Primero, el script que manda la notificación. Este ejemplo publica el mensaje en un tema de [ntfy](https://ntfy.sh), que acepta un simple `POST` con el texto en el cuerpo, y además lo deja registrado en el journal. Sustituye `your_ntfy_topic_url` por la URL de tu tema (por ejemplo `https://ntfy.sh/un-nombre-dificil-de-adivinar`) o por el webhook que ya uses: ```bash sudo nano /usr/local/bin/notify-unit-failure ``` ```bash #!/usr/bin/env bash set -euo pipefail unit="$1" host="$(hostname -f)" url="your_ntfy_topic_url" message="$(printf '%s ha fallado en %s\n\n%s' \ "$unit" "$host" \ "$(journalctl -u "$unit" -n 15 --no-pager -o cat)")" logger -t unit-failure "Unidad fallida: $unit" curl -fsS --max-time 10 -H "Title: Servicio caído en $host" -d "$message" "$url" > /dev/null ``` Hazlo ejecutable: ```bash sudo chmod 755 /usr/local/bin/notify-unit-failure ``` Ahora crea la unidad plantilla. El `@` en el nombre permite pasarle el servicio afectado como instancia, que llega al script a través de `%i`: ```bash sudo nano /etc/systemd/system/notify-failure@.service ``` ```ini [Unit] Description=Aviso de fallo para %i [Service] Type=oneshot ExecStart=/usr/local/bin/notify-unit-failure %i ``` Prueba la unidad de aviso directamente, sin esperar a un fallo real: ```bash sudo systemctl daemon-reload sudo systemctl start notify-failure@nginx.service journalctl -t unit-failure -n 1 --no-pager ``` ```output Sep 24 12:31:02 web01 unit-failure[5120]: Unidad fallida: nginx ``` Deberías recibir también la notificación en tu tema de ntfy. Cuando funcione, engancha el aviso al servicio abriendo de nuevo su override: ```bash sudo systemctl edit nginx ``` Añade `OnFailure=` a la sección `[Unit]` que ya tenías. El especificador `%N` se sustituye por el nombre de la unidad sin el sufijo (`nginx`), de modo que se arrancará `notify-failure@nginx.service`: ```ini [Unit] StartLimitIntervalSec=300 StartLimitBurst=5 OnFailure=notify-failure@%N.service [Service] Restart=on-failure RestartSec=5s ``` Comprueba que la dependencia está registrada: ```bash systemctl show nginx -p OnFailure ``` ```output OnFailure=notify-failure@nginx.service ``` Puedes reutilizar la misma plantilla en cualquier otro servicio añadiendo la misma línea `OnFailure=notify-failure@%N.service` a su override. ## Solución de problemas - **`systemctl edit` no guarda nada**: el contenido debe ir entre las líneas de comentario que marca el editor. Todo lo que escribas debajo de `### Edits below this comment will be discarded` se descarta. - **El servicio no se reinicia tras un `systemctl stop`**: es el comportamiento esperado. `Restart=` solo actúa cuando el proceso termina por sí mismo o por una señal externa. - **`Start request repeated too quickly`**: el servicio ha superado `StartLimitBurst`. Corrige la causa revisando `journalctl -u nombre_del_servicio`, ejecuta `sudo systemctl reset-failed nombre_del_servicio` y arráncalo de nuevo. - **No llega el aviso**: ejecuta `sudo systemctl status notify-failure@nginx.service` y `journalctl -u notify-failure@nginx.service` para ver el error del script, normalmente una URL mal copiada o sin salida a Internet. ## Conclusión Has usado `systemctl`, `journalctl` y `systemd-cgtop` para revisar el estado, los logs y el consumo de un servicio, has configurado reinicios automáticos con un límite razonable y has enlazado un aviso que se dispara cuando systemd se rinde. Todo con herramientas que ya vienen en Ubuntu 24.04. Como siguientes pasos puedes: - Configurar la retención y el almacenamiento persistente del journal para conservar más historial. - Limitar recursos por servicio con directivas como `MemoryMax=` o `CPUQuota=` en el mismo override. - Añadir una herramienta de monitorización externa (Prometheus con node_exporter, Zabbix) para tener métricas históricas y vigilar varios servidores a la vez.