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

341 lines
9.3 KiB
Markdown

# 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 "<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
- 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