[MEJORA] Salida visual mejorada para pipelines DASUTEN
Se implementó mejora en la salida de comandos para hacerla más intuitiva: Cambios realizados: - bkps.rb: Encabezado y cierre visual con box drawing para tareas DASUTEN - ejecutor.rb: Barra de progreso con timer en tiempo real durante ejecución - A04.P006: Actualizado con resultados del test completo 2026-04-15 Nueva salida visual: - Encabezado con contexto del pipeline (nombre, hora de inicio) - Timer en vivo durante la ejecución ([1m 23s] ejecutando...) - Cierre con estado (✅/❌) y duración total Resultados del test completo (Pipeline FULL): - 6 pasos completados exitosamente en 13m 15s - DBCC CHECKDB: Integridad OK - Todos los drones atómicos funcionaron correctamente Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
4a0cdd883e
commit
db86f86e59
+27
-2
@@ -750,7 +750,21 @@ module ADN
|
||||
end
|
||||
|
||||
t_inicio = Time.now
|
||||
@logger.info("▶ #{tarea[:texto]} (#{tipo})")
|
||||
|
||||
# Encabezado visual para tareas DASUTEN
|
||||
es_dasuten = (tipo == 'dasuten')
|
||||
if es_dasuten
|
||||
puts ""
|
||||
puts "╔═══════════════════════════════════════════════════════════╗"
|
||||
puts "║ 🔄 Pipeline DASUTEN — #{tarea[:texto].ljust(35)} ║"
|
||||
puts "╠═══════════════════════════════════════════════════════════╣"
|
||||
puts "║ Inicio: #{Time.now.strftime('%H:%M:%S')}".ljust(55) + "║"
|
||||
puts "╚═══════════════════════════════════════════════════════════╝"
|
||||
puts ""
|
||||
else
|
||||
@logger.info("▶ #{tarea[:texto]} (#{tipo})")
|
||||
end
|
||||
|
||||
procesador = factory.call(@logger)
|
||||
|
||||
# Modo atómico: procesar un solo archivo
|
||||
@@ -764,7 +778,18 @@ module ADN
|
||||
duracion = (Time.now - t_inicio).to_i
|
||||
mins = duracion / 60
|
||||
segs = duracion % 60
|
||||
@logger.info("✔ #{tarea[:texto]} — #{mins}m#{segs}s")
|
||||
|
||||
if es_dasuten
|
||||
estado = resultado ? "✅ Completado" : "❌ Fallido"
|
||||
puts ""
|
||||
puts "╔═══════════════════════════════════════════════════════════╗"
|
||||
puts "║ #{estado} — Duración: #{mins}m #{segs}s".ljust(55) + "║"
|
||||
puts "╚═══════════════════════════════════════════════════════════╝"
|
||||
puts ""
|
||||
else
|
||||
@logger.info("✔ #{tarea[:texto]} — #{mins}m#{segs}s")
|
||||
end
|
||||
|
||||
resultado
|
||||
end
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
require_relative 'base'
|
||||
require_relative '../../db/core/dron_db'
|
||||
require_relative '../../core/colores'
|
||||
require 'open3'
|
||||
require 'timeout'
|
||||
require 'time'
|
||||
@@ -81,19 +82,36 @@ module Dron
|
||||
last_out = ""
|
||||
accumulated_out = [] # Acumular todas las líneas de output para el heartbeat
|
||||
exit_code = nil
|
||||
progreso_visible = !ENV['BATCH_MODE'] # Solo mostrar progreso si no es batch
|
||||
|
||||
# Mostrar encabezado de progreso
|
||||
if progreso_visible
|
||||
puts "\n#{Color::BOLD}#{Color::CYAN}⏳ Ejecutando...#{Color::RESET}"
|
||||
print " ["
|
||||
$stdout.flush
|
||||
end
|
||||
|
||||
heartbeat_thread = Thread.new do
|
||||
tick = 0
|
||||
start = Time.now
|
||||
loop do
|
||||
sleep(HEARTBEAT_INTERVAL)
|
||||
tick += 1
|
||||
elapsed = (Time.now - start).to_i
|
||||
|
||||
# Actualizar tabla interna (dron_logs.heartbeat)
|
||||
ADN::DB::DronDB.actualizar_heartbeat(dron_id)
|
||||
|
||||
# Actualizar Bitácora Web (events.descripcion) — VISIBLE para el usuario
|
||||
# Pasamos el output acumulado para mostrar todo el progreso
|
||||
actualizar_heartbeat_web(evento_id, dron_id, nota, cmd, inicio, tick, accumulated_out.join("\n")) if evento_id
|
||||
|
||||
# Actualizar barra de progreso local
|
||||
if progreso_visible
|
||||
mins = elapsed / 60
|
||||
segs = elapsed % 60
|
||||
print "\r [#{Color::CYAN}#{mins}m #{segs}s#{Color::RESET}] ejecutando..."
|
||||
$stdout.flush
|
||||
end
|
||||
rescue StandardError => e
|
||||
Base.logger.warn("⚠️ Error en heartbeat ##{tick}: #{e.message}")
|
||||
end
|
||||
@@ -129,6 +147,13 @@ module Dron
|
||||
heartbeat_thread.exit
|
||||
end
|
||||
|
||||
# Finalizar barra de progreso
|
||||
if progreso_visible
|
||||
estado = exit_code == 0 ? "#{Color::GREEN}✅#{Color::RESET}" : "#{Color::RED}❌#{Color::RESET}"
|
||||
print "\r #{estado} "
|
||||
puts "#{Color::BOLD}Completado en #{Base.formato_duracion(Time.now - start_time)}#{Color::RESET}"
|
||||
end
|
||||
|
||||
raw_output = output.join("\n").strip
|
||||
safe_output = raw_output.dup.force_encoding('UTF-8').scrub('?')
|
||||
{ exit_code: exit_code || 1, output: safe_output, duration: (Time.now - start_time).round(2) }
|
||||
|
||||
@@ -18,6 +18,15 @@
|
||||
| **Fase 3: Pipeline Diferencial** | ✅ Completado | 100% |
|
||||
| **Fase 4: Integración BKPs** | ✅ Completado | 100% |
|
||||
| **Fase 5: Mejora de Latidos** | ✅ Completado | 100% |
|
||||
| **Fase 6: Validación Pipeline FULL** | ✅ Completado | 100% |
|
||||
|
||||
### Resumen de Validación (2026-04-15)
|
||||
|
||||
✅ **Pipeline COMPLETO validado de principio a fin**
|
||||
- Backup FULL exportado, transferido, subido, bajado, restaurado y verificado
|
||||
- Integridad de BD confirmada con DBCC CHECKDB: **OK**
|
||||
- Duración total: **13m 15s** (dentro de lo estimado: ~35-40 min)
|
||||
- Todos los drones atómicos funcionaron correctamente en modo orquestado
|
||||
|
||||
## 🎯 Objetivo
|
||||
|
||||
@@ -181,6 +190,79 @@ El procesador `Dasuten` fue integrado en `bkps.rb` como un nuevo tipo de tarea:
|
||||
| 2026-04-14 15:54 | Completo | 44.8s | 1.33 GB | ✅ |
|
||||
| 2026-04-14 16:03 | Diferencial | 2.44s | 0.39 MB | ✅ |
|
||||
| 2026-04-14 16:35 | Upload Drive | 23.79s | 0.39 MB | ✅ |
|
||||
| **2026-04-15 11:01** | **Pipeline FULL** | **13m 15s** | **~1.3 GB** | **✅ COMPLETO** |
|
||||
|
||||
### Detalle Pipeline 2026-04-15 (Test Completo)
|
||||
|
||||
| Paso | Tarea | Nodo | Duración | Estado |
|
||||
|------|-------|------|----------|--------|
|
||||
| 1 | `dasuten_export_full` | srvv-fenix | 46s | ✅ |
|
||||
| 2 | `dasuten_transferir` | srv-ns8 | 2s | ✅ |
|
||||
| 3 | `dasuten_upload` | srv-ns8 | 7m 9s | ✅ |
|
||||
| 4 | `dasuten_download` | dasu-sql4 | 52s | ✅ |
|
||||
| 5 | `dasuten_restaurar_full` | dasu-sql4 | 13s | ✅ |
|
||||
| 6 | `dasuten_verificar` | dasu-sql4 | 4m 11s | ✅ |
|
||||
|
||||
**Throughput:**
|
||||
- Upload a Drive: ~3 MB/s (limitado por ancho de banda de subida)
|
||||
- Download desde Drive: ~25 MB/s (HTTP directo)
|
||||
- Restore SQL: instantáneo (MOVE de archivos)
|
||||
- DBCC CHECKDB: ~1.2M páginas verificadas en 4m 11s
|
||||
|
||||
## 🧪 Sesión de Test Completa (2026-04-15)
|
||||
|
||||
**Objetivo:** Validar el pipeline completo de backup/restore usando **backup FULL** (no diferencial).
|
||||
|
||||
### Ejecución Orquestada (REINICIADA)
|
||||
|
||||
Se utiliza el comando **orquestado** `dasuten_full` que ejecuta los 6 pasos en secuencia automáticamente.
|
||||
|
||||
| Paso | ID Tarea | Dron | Nodo | Estado | Duración |
|
||||
|------|----------|------|------|--------|----------|
|
||||
| **1** | `dasuten_export_full` | `dasuten_exportar_srvv-fenix.rb` | srvv-fenix | ⏳ Pendiente | — |
|
||||
| **2** | `dasuten_transferir` | `dasuten_transferir_srvv-fenix-srv-ns8.rb` | srv-ns8 | ⏳ Pendiente | — |
|
||||
| **3** | `dasuten_upload` | `dasuten_upload_srv-ns8-drive.rb` | srv-ns8 | ⏳ Pendiente | — |
|
||||
| **4** | `dasuten_download` | `dasuten_download_drive-dasu-sql4.rb` | dasu-sql4 | ⏳ Pendiente | — |
|
||||
| **5** | `dasuten_restaurar_full` | `dasuten_restaurar_dasu-sql4.rb` | dasu-sql4 | ⏳ Pendiente | — |
|
||||
| **6** | `dasuten_verificar` | `dasuten_verificar-integridad_dasu-sql4.rb` | dasu-sql4 | ⏳ Pendiente | — |
|
||||
|
||||
**Comando orquestado:**
|
||||
|
||||
```bash
|
||||
# Ejecución completa (6 pasos en secuencia)
|
||||
./adn/tools/run bkps run dasuten_full --batch
|
||||
```
|
||||
|
||||
**Notas de la sesión:**
|
||||
- Tipo de backup: **FULL/COMPLETO** (~1.3 GB esperado)
|
||||
- Ejecución: **Orquestada** (un solo comando, 6 pasos automáticos)
|
||||
- Heartbeats acumulados: Se prueba la nueva mejora de latidos que muestra las últimas 15 líneas del progreso en Bitácora Web
|
||||
|
||||
---
|
||||
|
||||
### Registro de Ejecución — Test 2026-04-15
|
||||
|
||||
| Hora | Paso | Resultado | Duración | Observaciones |
|
||||
|------|------|-----------|----------|---------------|
|
||||
| 11:01 | 🚩 **TEST INICIADO** | — | — | Pipeline FULL orquestado (`dasuten_full --batch`) |
|
||||
| 11:01 | 1. Exportar | ✅ Completado | 46s | Backup FULL en `X:\` (srvv-fenix) |
|
||||
| 11:02 | 2. Transferir | ✅ Completado | 2s | SMB: fenix → ns8 (`/var/tmp/`) |
|
||||
| 11:02 | 3. Upload | ✅ Completado | 7m 9s | rclone: ns8 → Google Drive (~1.3 GB) |
|
||||
| 11:09 | 4. Download | ✅ Completado | 52s | HTTP: Drive → dasu-sql4 (`F:\BACKUP\`) |
|
||||
| 11:10 | 5. Restore | ✅ Completado | 13s | RESTORE DATABASE WITH REPLACE + MOVE |
|
||||
| 11:10 | 6. Verificar | ✅ Completado | 4m 11s | DBCC CHECKDB — Integridad: **OK** |
|
||||
| 11:14 | 🏁 **PIPELINE COMPLETADO** | ✅ | **13m 15s** | Todos los pasos exitosos |
|
||||
|
||||
**Resultados clave:**
|
||||
- ✅ Backup FULL de ~1.3 GB transferido correctamente
|
||||
- ✅ Google Drive como intermediario (sin dependencia de Tailscale)
|
||||
- ✅ Restore completado con MOVE a `F:\DATA` y `F:\LOG`
|
||||
- ✅ DBCC CHECKDB: **Integridad OK** (base de datos consistente)
|
||||
|
||||
---
|
||||
|
||||
**Ejecuciones anteriores (descartadas):**
|
||||
- Paso 4 (Restore diferencial): ✅ 14.7s — ejecutado de forma aislada, no corresponde a esta sesión FULL
|
||||
|
||||
## ⚠️ Consideraciones Técnicas
|
||||
|
||||
|
||||
Reference in New Issue
Block a user