service-monitor/docs/PROYECTO_COMPLETO.md
reugenio dbcf8c696b Documentación final proyecto completado
- docs/PROYECTO_COMPLETO.md: v1.2, SMTP STARTTLS documentado
- docs/DIARIO_DESARROLLO.md: Sesión 3 con migración Zig 0.15 y SMTP

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 01:24:15 +01:00

9.3 KiB

Service Monitor - Documentación Completa

Fecha: 2025-12-08 Versión: 1.2 Lenguaje: Zig 0.15.2 Repositorio: https://git.reugenio.com/reugenio/service-monitor

Descripción

Monitor de servicios HTTP y TCP para verificar disponibilidad del servidor Hetzner (Simba). Notifica por desktop, email y Telegram cuando hay servicios caídos.

Características Implementadas

Feature Estado Descripción
Verificación HTTP/HTTPS GET + status 200 + tiempo respuesta
Verificación TCP Conexión a puerto + DNS resolution
Modo watch Loop continuo con intervalo configurable
Modo daemon Background con fork() + setsid()
Log a archivo Append mode, timestamps ISO
Config externo Archivo CSV simple
Notificación desktop notify-send (Linux)
Notificación email SMTP con STARTTLS via curl
Notificación Telegram Bot API via curl

Estructura del Proyecto

service-monitor/
├── build.zig              # Sistema de build Zig
├── CLAUDE.md              # Especificación del proyecto
├── services.conf          # Configuración activa
├── services.conf.example  # Ejemplo documentado
├── service-monitor        # Binario compilado
├── service-monitor.log    # Log de ejecución
├── service-monitor.pid    # PID en modo daemon
│
├── src/
│   ├── main.zig           # Entry point + CLI + lógica principal (317 líneas)
│   ├── http.zig           # Cliente HTTP/HTTPS (77 líneas)
│   ├── tcp.zig            # Verificación TCP (68 líneas)
│   ├── config.zig         # Parser de configuración (233 líneas)
│   ├── notify.zig         # Notificaciones desktop (77 líneas)
│   ├── daemon.zig         # Daemonización (101 líneas)
│   ├── smtp.zig           # Cliente SMTP (260 líneas)
│   └── telegram.zig       # Cliente Telegram (107 líneas)
│
└── docs/
    ├── DIARIO_DESARROLLO.md
    └── PROYECTO_COMPLETO.md  # Este archivo

Uso

Comandos Básicos

# Compilar
zig build

# Verificar una vez
./service-monitor

# Modo watch (cada 60 segundos)
./service-monitor --watch

# Modo watch cada 30 segundos
./service-monitor -w -i 30

# Con log a archivo
./service-monitor -w -l

# Con notificaciones desktop
./service-monitor -w -n

# Daemon en background
./service-monitor -w -d

# Todo junto
./service-monitor -w -i 60 -d -l -n

# Config personalizado
./service-monitor -c /ruta/config.conf

# Ayuda
./service-monitor --help

Opciones CLI

Opción Corto Descripción Default
--watch -w Modo continuo false
--interval -i Segundos entre checks 60
--log -l Log a archivo service-monitor.log
--notify -n Notificaciones desktop false
--daemon -d Ejecutar en background false
--config -c Archivo de configuración services.conf
--help -h Mostrar ayuda -

Gestión del Daemon

# Iniciar daemon
./service-monitor -w -d -l -n

# Ver PID
cat service-monitor.pid

# Ver logs
tail -f service-monitor.log

# Detener daemon
kill $(cat service-monitor.pid)

Archivo de Configuración

Formato

# Comentarios con #
# tipo,parámetros...

# Servicios HTTP
http,Nombre Servicio,https://url.com

# Servicios TCP
tcp,Nombre Servicio,hostname,puerto

# Email (destinatarios)
email,destinatario@ejemplo.com

# Email (servidor SMTP)
email_smtp,smtp.servidor.com,puerto,usuario,password,from@email.com

# Telegram
telegram,bot_token,chat_id

Ejemplo Real (services.conf)

# Servicios HTTP
http,Forgejo (HTTP),https://git.reugenio.com
http,Simifactu API,https://simifactu.com
http,Mundisofa,https://mundisofa.com
http,Menzuri,https://menzuri.com

# Servicios TCP
tcp,Forgejo (SSH),git.reugenio.com,2222

# Telegram
telegram,8158165444:AAFxUjLChsuusgFD5B1gt2svt8NflvAm1M8,1481345275

Servicios Monitoreados (Servidor Simba)

Servicio Tipo Endpoint Puerto
Forgejo HTTP HTTPS git.reugenio.com 443
Forgejo SSH TCP git.reugenio.com 2222
Simifactu HTTPS simifactu.com 443
Mundisofa HTTPS mundisofa.com 443
Menzuri HTTPS menzuri.com 443

Output

Terminal (con colores)

[2025-12-07 20:53:24]
✓ Forgejo (HTTP) - OK (768ms)
✓ Forgejo (SSH) - OK (63ms)
✓ Simifactu API - OK (481ms)
✓ Mundisofa - OK (444ms)
✓ Menzuri - OK (456ms)

Log (sin colores)

[2025-12-07 20:53:24]
OK Forgejo (HTTP) (768ms)
OK Forgejo (SSH) (63ms)
OK Simifactu API (481ms)
OK Mundisofa (444ms)
OK Menzuri (456ms)

Telegram (cuando hay errores)

⚠️ ALERTA: Servicios caídos

- Nombre Servicio 1
- Nombre Servicio 2

Detalles Técnicos por Módulo

main.zig

  • Entry point de la aplicación
  • Parser de argumentos CLI
  • Lógica de loop watch/daemon
  • Coordinación de todos los módulos
  • Gestión de timestamps (UTC)

http.zig

  • Cliente HTTP usando std.http.Client
  • Soporte HTTPS con TLS automático
  • Buffer de headers: 8192 bytes
  • Medición de tiempo de respuesta
  • Errores tipados: DnsResolutionFailed, ConnectionFailed, Timeout, UnexpectedStatus

tcp.zig

  • Conexión TCP con std.net.tcpConnectToHost
  • Resolución DNS automática
  • Medición de tiempo de conexión
  • Errores tipados: DnsResolutionFailed, ConnectionRefused, Timeout

config.zig

  • Parser CSV simple
  • Soporte para comentarios (#)
  • Estructuras: Service, SmtpConfig, TelegramConfig, Config
  • Fallback a config por defecto si no existe archivo
  • Gestión de memoria con allocator

notify.zig

  • Wrapper sobre notify-send
  • Niveles de urgencia: low, normal, critical
  • Funciones: send(), sendError(), sendRecovery()

daemon.zig

  • Double fork para daemonización correcta
  • Syscall directo para setsid() (no disponible en std.posix Zig 0.13)
  • Redirección de stdin/stdout/stderr a /dev/null
  • Escritura de PID file
  • Cambio a directorio raíz

smtp.zig

  • Implementación SMTP usando curl como subprocess
  • Soporte completo STARTTLS (puerto 587)
  • Curl maneja TLS de forma transparente
  • Autenticación con usuario/contraseña
  • Compatible con Gmail, Mailbox.org, Outlook, etc.

telegram.zig

  • Bot API via curl (más fiable que std.http para POST)
  • Funciones: sendMessage(), sendAlert()
  • Formato de mensaje con lista de servicios

Consumo de Recursos

Recurso Valor
RAM ~2-5 MB
CPU (idle) ~0%
CPU (check) <1% por ~2s
Binario ~8.4 MB (debug)
Red ~10KB por ciclo

Commits Históricos

Hash Descripción
e2e19da Fase 1: Monitor básico HTTP/TCP
3946f83 Fase 2: Modo watch + CLI + timestamps
dfcfd31 Log a archivo
5a17d74 Fase 3: Notificaciones desktop
655dcb8 Daemon mode + config externo
a011d9e SMTP y Telegram
f31ce95 Migración a Zig 0.15.2
4a9d0e6 SMTP con STARTTLS via curl

Pendiente

  • SMTP con STARTTLS (completado 2025-12-08 via curl)
  • Migración a Zig 0.15 (completado 2025-12-08)
  • Notificación de recuperación (servicio vuelve a funcionar)
  • Rate limiting de notificaciones (evitar spam)
  • Métricas/estadísticas de uptime

Notas de Migración a Zig 0.15

La migración a Zig 0.15.2 requirió los siguientes cambios:

Cambio Antes (0.13) Después (0.15)
Build.zig root_source_file root_module con b.createModule()
stdout std.io.getStdOut().writer() std.fs.File.stdout().deprecatedWriter()
ArrayList std.ArrayList(T).init(alloc) std.array_list.Managed(T).init(alloc)
file.reader() sin args requiere buffer, usar deprecatedReader()
HTTP Client client.open() + send() + wait() client.fetch()
sleep std.time.sleep() std.Thread.sleep()

Notas de Implementación SMTP con STARTTLS

La implementación nativa de TLS en Zig 0.15 resultó compleja debido a cambios en la API de I/O. Se optó por usar curl como subprocess, que ofrece:

  • Simplicidad: curl maneja STARTTLS transparentemente con --ssl-reqd
  • Fiabilidad: curl es estable y bien probado
  • Compatibilidad: Funciona con cualquier servidor SMTP moderno
  • Consistencia: Mismo enfoque que Telegram (también usa curl)
# Equivalente manual:
echo -e "From: user@mailbox.org\r\nTo: dest@example.com\r\nSubject: Test\r\n\r\nBody" | \
curl -s --url "smtp://smtp.mailbox.org:587" --ssl-reqd \
  -u "user@mailbox.org:password" \
  --mail-from "<user@mailbox.org>" \
  --mail-rcpt "<dest@example.com>" -T -

Configuración SMTP Actual

Parámetro Valor
Servidor smtp.mailbox.org
Puerto 587 (STARTTLS)
Usuario reugenio@mailbox.org
Tipo password App password (solo envío)

Nota: Credenciales completas en TEAM_STANDARDS/INFRASTRUCTURE/NOTIFICACIONES.md

Referencias