# 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 ```bash # 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 ```bash # 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 - [x] ~~SMTP con STARTTLS~~ (completado 2025-12-08 via curl) - [x] ~~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) ```bash # 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 "" \ --mail-rcpt "" -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 - Zig 0.15 stdlib: https://ziglang.org/documentation/0.15.0/std/ - SMTP RFC 5321: https://tools.ietf.org/html/rfc5321 - Telegram Bot API: https://core.telegram.org/bots/api - Guía Zig 0.15: /mnt/cello2/arno/re/recode/TEAM_STANDARDS/INFRASTRUCTURE/ZIG_0.15_GUIA.md - Credenciales: /mnt/cello2/arno/re/recode/TEAM_STANDARDS/INFRASTRUCTURE/NOTIFICACIONES.md