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:
- Detección: Monitoreo y alertas
- Diagnóstico: Análisis de logs y métricas
- Solución: Aplicación de parches o configuraciones
- Verificación: Confirmación de resolución
- 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