Mantenimiento y Operaciones

Mantenimiento y Operaciones

Gestión de Mantenimiento

Tipos de Mantenimiento

1. Mantenimiento Preventivo

Frecuencia: Diario, semanal, mensual Objetivo: Prevenir fallos antes de que ocurran

Tareas Diarias:

  • Monitoreo de logs de errores
  • Verificación de espacio en disco
  • Revisión de uso de CPU y memoria
  • Validación de backups automáticos

Tareas Semanales:

  • Análisis de rendimiento
  • Revisión de actualizaciones de seguridad
  • Limpieza de logs antiguos
  • Verificación de certificados SSL

Tareas Mensuales:

  • Actualización de dependencias
  • Optimización de base de datos
  • Revisión de políticas de retención
  • Auditoría de accesos

2. Mantenimiento Correctivo

Frecuencia: Según necesidad Objetivo: Resolver problemas cuando ocurren

Procedimiento:

  1. Detección: Monitoreo y alertas
  2. Diagnóstico: Análisis de logs y métricas
  3. Solución: Aplicación de parches o configuraciones
  4. Verificación: Confirmación de resolución
  5. Documentación: Registro del incidente

3. Mantenimiento Evolutivo

Frecuencia: Trimestral o según roadmap Objetivo: Mejoras y nuevas funcionalidades

Gestión de Logs

Configuración de Logging

Niveles de Log

// config/logging.js
module.exports = {
  levels: {
    error: 0,
    warn: 1,
    info: 2,
    debug: 3
  },
  format: 'combined',
  transports: [
    {
      type: 'file',
      filename: '/app/logs/error.log',
      level: 'error',
      maxSize: '10m',
      maxFiles: 5
    },
    {
      type: 'file',
      filename: '/app/logs/combined.log',
      maxSize: '50m',
      maxFiles: 10
    },
    {
      type: 'console',
      colorize: true
    }
  ]
};

Estructura de Logs

{
  "timestamp": "2023-01-01T12:00:00.000Z",
  "level": "info",
  "message": "Document processed successfully",
  "service": "dtem-api",
  "requestId": "req_123456",
  "userId": "user_789",
  "documentId": "doc_456",
  "duration": 150,
  "metadata": {
    "documentType": "invoice",
    "amount": 100000,
    "currency": "CLP"
  }
}

Análisis de Logs

Comandos Útiles

# Ver logs en tiempo real
tail -f /app/logs/combined.log

# Filtrar por nivel
grep "ERROR" /app/logs/combined.log

# Filtrar por fecha
grep "2023-01-01" /app/logs/combined.log

# Contar errores por hora
grep "ERROR" /app/logs/combined.log | awk '{print $1}' | sort | uniq -c

# Extraer IPs de acceso
grep -oP '\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b' /app/logs/access.log

ELK Stack Configuration

# elasticsearch.yml
cluster.name: dtem-cluster
node.name: node-1
path.data: /usr/share/elasticsearch/data
path.logs: /usr/share/elasticsearch/logs
network.host: 0.0.0.0
discovery.type: single-node
xpack.security.enabled: false
# logstash.conf
input {
  file {
    path => "/app/logs/*.log"
    start_position => "beginning"
    codec => json
  }
}

filter {
  if [level] == "ERROR" {
    mutate {
      add_tag => ["alert"]
    }
  }
  
  date {
    match => [ "timestamp", "ISO8601" ]
  }
}

output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "dtem-logs-%{+YYYY.MM.dd}"
  }
  
  if "alert" in [tags] {
    email {
      to => "admin@yourdomain.com"
      subject => "DTEM Alert: %{[message]}"
      body => "Error detected in DTEM: %{[message]}"
    }
  }
}

Gestión de Backups

Estrategia de Backup

1. Base de Datos

#!/bin/bash
# backup-database.sh

BACKUP_DIR="/backup/database"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="dtem"
DB_USER="dtem_user"

# Crear backup completo
pg_dump -h localhost -U $DB_USER -d $DB_NAME -F c -b -v -f "$BACKUP_DIR/dtem_full_$DATE.backup"

# Crear backup de estructura
pg_dump -h localhost -U $DB_USER -d $DB_NAME -s -f "$BACKUP_DIR/dtem_schema_$DATE.sql"

# Comprimir backup
gzip "$BACKUP_DIR/dtem_full_$DATE.backup"

# Eliminar backups antiguos (más de 30 días)
find $BACKUP_DIR -name "*.backup.gz" -mtime +30 -delete
find $BACKUP_DIR -name "*.sql" -mtime +30 -delete

echo "Backup de base de datos completado: dtem_full_$DATE.backup.gz"

2. Archivos y Certificados

#!/bin/bash
# backup-files.sh

BACKUP_DIR="/backup/files"
DATE=$(date +%Y%m%d_%H%M%S)

# Backup de certificados
tar -czf "$BACKUP_DIR/certificates_$DATE.tar.gz" /app/certificates/

# Backup de configuración
tar -czf "$BACKUP_DIR/config_$DATE.tar.gz" /app/config/

# Backup de logs (últimos 7 días)
find /app/logs -name "*.log" -mtime -7 -exec tar -czf "$BACKUP_DIR/logs_$DATE.tar.gz" {} +

# Eliminar backups antiguos
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete

echo "Backup de archivos completado"

3. Automatización con Cron

# crontab -e
# Backup diario de base de datos a las 2 AM
0 2 * * * /usr/local/bin/backup-database.sh

# Backup diario de archivos a las 3 AM
0 3 * * * /usr/local/bin/backup-files.sh

# Backup semanal completo el domingo a las 1 AM
0 1 * * 0 /usr/local/bin/backup-full.sh

# Verificación de backups diaria a las 8 AM
0 8 * * * /usr/local/bin/verify-backups.sh

Restauración

Restauración de Base de Datos

#!/bin/bash
# restore-database.sh

BACKUP_FILE=$1
DB_NAME="dtem"
DB_USER="dtem_user"

if [ -z "$BACKUP_FILE" ]; then
    echo "Uso: $0 <archivo_de_backup>"
    exit 1
fi

# Detener aplicación
systemctl stop dtem

# Restaurar base de datos
pg_restore -h localhost -U $DB_USER -d $DB_NAME -v -c "$BACKUP_FILE"

# Iniciar aplicación
systemctl start dtem

echo "Restauración completada"

Monitoreo y Alertas

Métricas Clave

1. Métricas de Aplicación

// metrics.js
const prometheus = require('prom-client');

// Crear métricas
const httpRequestDuration = new prometheus.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Duration of HTTP requests in seconds',
  labelNames: ['method', 'route', 'status_code'],
  buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10]
});

const httpRequestTotal = new prometheus.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'route', 'status_code']
});

const activeConnections = new prometheus.Gauge({
  name: 'active_connections',
  help: 'Number of active connections'
});

const documentsProcessed = new prometheus.Counter({
  name: 'documents_processed_total',
  help: 'Total number of documents processed',
  labelNames: ['type', 'status']
});

// Middleware para Express
app.use((req, res, next) => {
  const start = Date.now();
  
  res.on('finish', () => {
    const duration = (Date.now() - start) / 1000;
    
    httpRequestDuration
      .labels(req.method, req.route?.path || req.path, res.statusCode)
      .observe(duration);
      
    httpRequestTotal
      .labels(req.method, req.route?.path || req.path, res.statusCode)
      .inc();
  });
  
  next();
});

2. Métricas de Base de Datos

-- Consultas para monitoreo PostgreSQL

-- Conexiones activas
SELECT count(*) as active_connections 
FROM pg_stat_activity 
WHERE state = 'active';

-- Tamaño de base de datos
SELECT pg_size_pretty(pg_database_size('dtem'));

-- Consultas lentas
SELECT query, mean_time, calls, total_time
FROM pg_stat_statements
ORDER BY mean_time DESC
LIMIT 10;

-- Bloqueos
SELECT blocked_locks.pid AS blocked_pid,
       blocked_activity.usename AS blocked_user,
       blocking_locks.pid AS blocking_pid,
       blocking_activity.usename AS blocking_user,
       blocked_activity.query AS blocked_statement,
       blocking_activity.query AS current_statement_in_blocking_process
FROM pg_catalog.pg_locks blocked_locks
JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_catalog.pg_locks blocking_locks ON blocking_locks.locktype = blocked_locks.locktype
JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;

Reglas de Alertas

Prometheus Alert Rules

# alert_rules.yml
groups:
- name: dtem_alerts
  rules:
  - alert: HighErrorRate
    expr: rate(http_requests_total{status_code=~"5.."}[5m]) > 0.1
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "High error rate detected"
      description: "Error rate is {{ $value }} errors per second"

  - alert: HighResponseTime
    expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 2
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High response time detected"
      description: "95th percentile response time is {{ $value }} seconds"

  - alert: DatabaseConnectionsHigh
    expr: pg_stat_database_numbackends > 80
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "High database connections"
      description: "Database has {{ $value }} active connections"

  - alert: DiskSpaceHigh
    expr: (node_filesystem_size_bytes - node_filesystem_free_bytes) / node_filesystem_size_bytes > 0.9
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "Disk space usage high"
      description: "Disk usage is {{ $value | humanizePercentage }}"

  - alert: ServiceDown
    expr: up == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Service is down"
      description: "{{ $labels.instance }} has been down for more than 1 minute"

Gestión de Actualizaciones

Estrategia de Actualización

1. Actualizaciones de Seguridad

#!/bin/bash
# security-updates.sh

# Actualizar paquetes del sistema
sudo apt update
sudo apt upgrade -y

# Actualizar dependencias de Node.js
npm audit fix

# Actualizar dependencias de Docker
docker-compose pull

# Reiniciar servicios
systemctl restart dtem
docker-compose up -d

echo "Actualizaciones de seguridad completadas"

2. Actualizaciones de Aplicación

#!/bin/bash
# update-application.sh

VERSION=$1
BACKUP_DIR="/backup/before-update-$(date +%Y%m%d_%H%M%S)"

# Crear backup antes de actualizar
mkdir -p $BACKUP_DIR
pg_dump -h localhost -U dtem_user dtem > $BACKUP_DIR/pre_update.sql

# Descargar nueva versión
wget https://releases.csc-chile.com/dtem/$VERSION/dtem-app.tar.gz
tar -xzf dtem-app.tar.gz

# Instalar dependencias
npm ci --production

# Ejecutar migraciones
npm run migrate

# Reiniciar aplicación
systemctl restart dtem

# Verificar estado
sleep 10
curl -f http://localhost:8080/api/health

if [ $? -eq 0 ]; then
    echo "Actualización completada exitosamente"
else
    echo "Error en actualización, restaurando backup..."
    pg_restore -h localhost -U dtem_user -d dtem $BACKUP_DIR/pre_update.sql
    systemctl restart dtem
    exit 1
fi

Blue-Green Deployment

#!/bin/bash
# blue-green-deploy.sh

NEW_VERSION=$1
CURRENT_ENV=$(kubectl get service dtem-service -o jsonpath='{.spec.selector.version}')

if [ "$CURRENT_ENV" = "blue" ]; then
    NEW_ENV="green"
else
    NEW_ENV="blue"
fi

# Desplegar nueva versión
kubectl apply -f k8s/deployment-$NEW_ENV.yaml
kubectl set image deployment/dtem-$NEW_ENV dtem-app=dtem/app:$NEW_VERSION

# Esperar que esté listo
kubectl rollout status deployment/dtem-$NEW_ENV

# Verificar salud
kubectl exec deployment/dtem-$NEW_ENV -- curl -f http://localhost:8080/api/health

if [ $? -eq 0 ]; then
    # Cambiar tráfico
    kubectl patch service dtem-service -p '{"spec":{"selector":{"version":"'$NEW_ENV'"}}}'
    echo "Tráfico cambiado a $NEW_ENV"
else
    # Rollback
    kubectl delete deployment dtem-$NEW_ENV
    echo "Error en despliegue, manteniendo versión actual"
    exit 1
fi

Gestión de Incidentes

Procedimiento de Respuesta a Incidentes

1. Clasificación de Incidentes

  • Crítico: Sistema completamente inoperativo
  • Alto: Funcionalidad principal afectada
  • Medio: Funcionalidad secundaria afectada
  • Bajo: Problemas menores o mejoras

2. Tiempos de Respuesta (SLA)

  • Crítico: 15 minutos para respuesta, 4 horas para resolución
  • Alto: 1 hora para respuesta, 8 horas para resolución
  • Medio: 4 horas para respuesta, 24 horas para resolución
  • Bajo: 24 horas para respuesta, 72 horas para resolución

3. Comunicación de Incidentes

#!/bin/bash
# incident-notify.sh

SEVERITY=$1
DESCRIPTION=$2
SERVICE=$3

# Enviar email
echo "Incidente en $SERVICE: $DESCRIPTION" | mail -s "Alerta $SEVERITY: $SERVICE" admin@yourdomain.com

# Enviar Slack (opcional)
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"🚨 Incidente '$SEVERITY' en '$SERVICE': '$DESCRIPTION'"}' \
$SLACK_WEBHOOK_URL

# Crear ticket en sistema de gestión (opcional)
curl -X POST https://your-ticket-system.com/api/tickets \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
  "title": "Incidente '$SEVERITY' en '$SERVICE'",
  "description": "'$DESCRIPTION'",
  "priority": "'$SEVERITY'",
  "service": "'$SERVICE'"
}'

Post-Mortem

Plantilla de Post-Mortem

# Post-Mortem: [Título del Incidente]

## Resumen Ejecutivo
- **Fecha y hora**: [Fecha/Hora del incidente]
- **Duración**: [Tiempo total de resolución]
- **Impacto**: [Descripción del impacto]
- **Severidad**: [Nivel de severidad]

## Línea de Tiempo
- **HH:MM**: Detección del problema
- **HH:MM**: Inicio de investigación
- **HH:MM**: Identificación de causa raíz
- **HH:MM**: Aplicación de solución
- **HH:MM**: Verificación de resolución
- **HH:MM**: Comunicación a stakeholders

## Causa Raíz
- **Causa directa**: [Causa inmediata]
- **Causas contribuyentes**: [Factores que contribuyeron]
- **Causa fundamental**: [Problema de base]

## Impacto
- **Usuarios afectados**: [Número de usuarios]
- **Transacciones perdidas**: [Cantidad]
- **Pérdida económica**: [Monto si aplica]
- **Reputación**: [Impacto en reputación]

## Lecciones Aprendidas
- **Qué funcionó bien**: [Aspectos positivos]
- **Qué podría mejorar**: [Aspectos a mejorar]
- **Acciones correctivas**: [Planes de acción]

## Acciones Preventivas
1. [Acción 1] - Responsable: [Nombre] - Fecha: [Fecha límite]
2. [Acción 2] - Responsable: [Nombre] - Fecha: [Fecha límite]
3. [Acción 3] - Responsable: [Nombre] - Fecha: [Fecha límite]

Próxima sección: Seguridad