Skip to content

Commit f5506b6

Browse files
Update documentation: added dashboard module, memory context for IA, and preparation for further sync_mysql_remote improvements
0 parents  commit f5506b6

15 files changed

+1316
-0
lines changed

README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# MySQL-Admin Project
2+
3+
## Descripción del Proyecto
4+
5+
El proyecto **MySQL-Admin** es una solución integral destinada a la administración, sincronización y migración de bases de datos MySQL. La arquitectura del sistema está diseñada para soportar múltiples flujos de datos:
6+
7+
- **Sincronización de bases de datos MySQL remotas a locales**: A través del script `sync_mysql_remote.py`, en fase de pruebas, se replican datos de bases MySQL remotas al entorno local para facilitar pruebas y migraciones iniciales.
8+
9+
- **Monitoreo en producción**: El script `mysql_monitor.py` se ejecuta en producción generando registros cada minuto para realizar análisis en tiempo real, detectar anomalías y mantener la salud de la base de datos.
10+
11+
- **Migración y sincronización hacia MongoDB**: Con `sync_mysql_mongo.py`, se permite la migración automática de una o varias bases de datos MySQL a MongoDB. Además, está diseñado para ejecutarse de forma iterativa, de modo que la base de datos sincronizada en MongoDB pueda servir, en futuras iteraciones, como fuente para sincronizar otra base MySQL remota y así desacoplar el motor MySQL local de tareas adicionales.
12+
13+
## Arquitectura y Flujo de Datos
14+
15+
El proyecto sigue una arquitectura modular que permite separar los roles y responsabilidades de cada componente:
16+
17+
1. **Sincronización Local y Remota**: Replicar tablas de bases de datos MySQL de un entorno remoto al local.
18+
2. **Monitoreo Continuo**: Recolección de datos y generación de logs periódicos para análisis y alertas.
19+
3. **Migración a MongoDB**: Consolidar datos de MySQL en MongoDB, ofreciendo flexibilidad y escalabilidad en el manejo de datos, con la posibilidad de servir como puente para sincronizaciones posteriores.
20+
21+
## Módulos del Proyecto
22+
23+
### Módulos Terminados y en Producción
24+
25+
- **`mysql_monitor.py`**: En ejecución en producción. Este módulo genera registros (logs) una vez por minuto para monitorizar el estado y rendimiento de la base de datos MySQL local.
26+
- **`sync_mysql_mongo.py`**: Funciona correctamente según lo esperado. Inicialmente permite la migración automática de bases de datos MySQL a MongoDB. Además, su diseño iterativo posibilita, en futuras versiones, que la base sincronizada en MongoDB se utilice para sincronizar otra base MySQL remota, permitiendo un desacople del motor MySQL local.
27+
- **`mongo_analytics.py`**: En producción. Se encarga del análisis y procesamiento de datos provenientes de MongoDB para generar reportes y métricas adicionales.
28+
- **`monitor_cron.py`**: En producción. Este script se ejecuta periódicamente para almacenar métricas en MongoDB y garantizar la supervisión continua de los datos.
29+
- **`dashboard.py`**: En producción. Proporciona un dashboard interactivo accesible vía navegador, visualizando métricas de MySQL (uso de CPU, uso de memoria y transacciones) en tiempo real con gráficos interactivos y responsive. Permite seleccionar múltiples intervalos de tiempo para el análisis.
30+
31+
> **Nota para IA:** Los módulos mencionados arriba están terminados y en funcionamiento. No se deben realizar modificaciones sobre estos módulos a menos que exista una autorización y acuerdo explícito por parte del desarrollador humano.
32+
33+
### Módulos en Fase de Prueba
34+
35+
- **`sync_mysql_remote.py`**: Actualmente en fase de prueba, se encarga de sincronizar bases de datos MySQL de un entorno remoto al local. Este módulo es utilizado para validar la replicación y sirve como base para migraciones iniciales o pruebas de concepto.
36+
37+
## Configuración
38+
39+
1. **Variables de Entorno**: El proyecto utiliza un archivo `.env` para gestionar parámetros críticos de conexión, tales como:
40+
- Para conexiones remotas: `DBR_HOST`, `DBR_PORT`, `DBR_USERNAME`, `DBR_PASSWORD`.
41+
- Para conexiones locales: `DB_HOST`, `DB_PORT`, `DB_USERNAME`, `DB_PASSWORD`.
42+
- Listado de bases de datos a sincronizar: `MYSQL_DATABASES` (una lista separada por comas).
43+
44+
2. **Instalación de Dependencias**: Asegúrate de tener instaladas las librerías requeridas (por ejemplo, `mysql-connector-python` y `python-dotenv`). Puedes instalarlas utilizando:
45+
46+
```bash
47+
pip install mysql-connector-python python-dotenv
48+
```
49+
50+
## Uso
51+
52+
- **Pruebas de Sincronización:** Ejecuta `sync_mysql_remote.py` para validar la sincronización entre bases de datos MySQL remotas y locales.
53+
- **Monitoreo en Producción:** El script `mysql_monitor.py` se ejecuta de manera continua para generar logs y vigilar el estado de la base de datos local.
54+
- **Migración a MongoDB:** Utiliza `sync_mysql_mongo.py` para migrar y mantener sincronizadas las bases de datos MySQL con su contraparte en MongoDB.
55+
56+
## Consideraciones Generales
57+
58+
- **Seguridad:** La construcción dinámica de consultas SQL requiere especial atención para evitar inyección SQL. Se asume que las variables de entorno están gestionadas de forma segura.
59+
60+
- **Integridad de Datos:** Durante la sincronización, se deshabilitan temporalmente las restricciones de claves foráneas para permitir el truncado de tablas. Se recomienda evaluar la restauración de estas restricciones post-sincronización si es necesaria para garantizar la integridad referencial.
61+
62+
- **Colaboración IA-Humano:** Este documento está pensado para servir tanto de guía para desarrolladores humanos como de referencia para sistemas IA. Las decisiones técnicas, metodológicas y el historial de cambios se documentan aquí para facilitar la colaboración continua y conservar la memoria de los procesos del proyecto.
63+
64+
## Memoria y Contexto para IA
65+
66+
Esta sección está destinada exclusivamente para el uso interno de la IA y como mecanismo de apoyo para reconstruir la memoria contextual del proyecto en futuras sesiones. Se recomienda que, en cualquier interacción, la IA utilice la información contenida en este README.md junto con las MEMORIES previas para mantener una perspectiva integral del proyecto.
67+
68+
- **Arquitectura General:** El proyecto integra sincronización de datos entre MySQL y MongoDB, así como monitoreo en tiempo real de las bases de datos.
69+
- **Módulos Clave:**
70+
- `sync_mysql_remote.py`: Sincronización de bases MySQL remotas a locales (en fase de prueba).
71+
- `mysql_monitor.py`: Monitoreo en producción, generando logs cada minuto.
72+
- `sync_mysql_mongo.py`: Migración y sincronización de datos desde MySQL hacia MongoDB, con posibles usos futuros para desacoplar procesos.
73+
- `mongo_analytics.py`: Análisis y procesamiento de datos provenientes de MongoDB en producción.
74+
- `monitor_cron.py`: Ejecución periódica para almacenar métricas en MongoDB y garantizar la supervisión continua.
75+
- `dashboard.py`: Proporciona un dashboard interactivo para visualizar métricas de MySQL en tiempo real.
76+
77+
- **Decisiones Técnicas:** Las variables de entorno y la modularidad en los scripts permiten un manejo flexible y seguro de las conexiones a bases de datos, asegurando la integridad de los datos durante la migración y sincronización.
78+
79+
- **Directrices para Colaboración IA-Humano:** Los módulos que se encuentran en producción no deben ser modificados sin autorización explícita del desarrollador humano. El documento README.md, junto con las MEMORIES, sirve para conservar la historia de decisiones y facilitar el trabajo colaborativo.
80+
81+
## Próximos Pasos
82+
83+
- Revisión de los parámetros de sincronización y migración.
84+
- Experimentación controlada para desacoplar el motor MySQL local utilizando la base consolidada en MongoDB.
85+
- Incrementar pruebas y validaciones en el módulo `sync_mysql_remote.py` antes de avanzar a producción.
86+
87+
---
88+
89+
*Documentación dual para procesos institucionales y colaboración entre IA y desarrollador humano.*
6.04 KB
Binary file not shown.

analyze_metrics.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import os
2+
import sys
3+
import datetime
4+
from pymongo import MongoClient
5+
from dotenv import load_dotenv
6+
7+
# Cargar variables de entorno
8+
load_dotenv()
9+
10+
11+
def get_db_connection():
12+
"""
13+
Establece la conexión a la base de datos MongoDB utilizando las credenciales del entorno.
14+
"""
15+
mongo_uri = f"mongodb://{os.getenv('MONGO_USERNAME')}:{os.getenv('MONGO_PASSWORD')}@{os.getenv('MONGO_HOST')}:27017/"
16+
try:
17+
client = MongoClient(mongo_uri)
18+
db = client['mysql_monitor']
19+
return db
20+
except Exception as e:
21+
sys.exit(f"Error al conectar a MongoDB: {e}")
22+
23+
24+
def analyze_metrics(limit=10):
25+
"""
26+
Recupera y muestra las métricas más recientes almacenadas en la colección 'metrics' de la base 'mysql_monitor'.
27+
28+
Parámetros:
29+
- limit: Número máximo de documentos a recuperar (por defecto 10).
30+
"""
31+
db = get_db_connection()
32+
collection = db['metrics']
33+
34+
# Recuperar los documentos de métricas ordenados de forma descendente por timestamp
35+
try:
36+
docs = list(collection.find().sort("timestamp", -1).limit(limit))
37+
except Exception as e:
38+
sys.exit(f"Error al obtener métricas: {e}")
39+
40+
if not docs:
41+
print("No se encontraron métricas en la base de datos.")
42+
return
43+
44+
print(f"Mostrando las {len(docs)} métricas más recientes:\n")
45+
for doc in docs:
46+
ts = datetime.datetime.fromtimestamp(doc.get("timestamp", 0), datetime.timezone.utc)
47+
# Excluimos el _id para una salida más limpia
48+
metrics_info = { key: value for key, value in doc.items() if key != '_id' }
49+
print(f"Timestamp: {ts.isoformat()}\nMétricas: {metrics_info}\n{'-'*40}")
50+
51+
52+
if __name__ == "__main__":
53+
# Se puede extender con argumentos de línea de comando para análisis más avanzados
54+
analyze_metrics()

dashboard.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import os
2+
import datetime
3+
from flask import Flask, request
4+
from pymongo import MongoClient
5+
import plotly.graph_objs as go
6+
import plotly.offline as opy
7+
from dotenv import load_dotenv
8+
9+
# Cargar variables de entorno
10+
deprecated_load = load_dotenv()
11+
12+
app = Flask(__name__)
13+
14+
15+
def get_db_connection():
16+
"""Establece la conexión a la base de datos MongoDB usando las credenciales del entorno."""
17+
mongo_uri = f"mongodb://{os.getenv('MONGO_USERNAME')}:{os.getenv('MONGO_PASSWORD')}@{os.getenv('MONGO_HOST')}:27017/"
18+
client = MongoClient(mongo_uri)
19+
db = client['mysql_monitor']
20+
return db
21+
22+
23+
@app.route('/')
24+
def index():
25+
# Obtener el intervalo deseado a través de parámetros de URL; por defecto 1h
26+
interval = request.args.get('interval', '1h')
27+
now = datetime.datetime.now(datetime.timezone.utc)
28+
29+
# Determinar el tiempo de inicio en función del intervalo
30+
if interval == '1h':
31+
start_time = now - datetime.timedelta(hours=1)
32+
elif interval == '6h':
33+
start_time = now - datetime.timedelta(hours=6)
34+
elif interval == '24h':
35+
start_time = now - datetime.timedelta(hours=24)
36+
elif interval == '30d':
37+
start_time = now - datetime.timedelta(days=30)
38+
else:
39+
start_time = now - datetime.timedelta(hours=1)
40+
41+
start_ts = start_time.timestamp()
42+
43+
# Conexión a la base de datos y recuperación de métricas
44+
db = get_db_connection()
45+
collection = db['metrics']
46+
data = list(collection.find({"timestamp": {"$gte": start_ts}}).sort("timestamp", 1))
47+
48+
if not data:
49+
return f"No se encontraron métricas para el intervalo {interval}"
50+
51+
# Extraer datos
52+
times = [datetime.datetime.fromtimestamp(doc['timestamp'], datetime.timezone.utc) for doc in data]
53+
cpu = [doc.get("mysql_cpu_usage_percent", 0) for doc in data]
54+
memory = [doc.get("mysql_memory_used_bytes", 0) for doc in data]
55+
# Utilizar el campo 'Questions' para calcular las transacciones
56+
questions = [doc.get("Questions", 0) for doc in data]
57+
58+
# Calcular transacciones por intervalo (diferencia entre registros consecutivos)
59+
transactions = [0] # primer registro no tiene comparación
60+
for i in range(1, len(questions)):
61+
transactions.append(questions[i] - questions[i - 1])
62+
63+
# Crear trazas para cada métrica
64+
trace_cpu = go.Scatter(x=times, y=cpu, mode='lines+markers', name='CPU Usage (%)')
65+
trace_memory = go.Scatter(x=times, y=memory, mode='lines+markers', name='Memory Used (Bytes)')
66+
trace_transactions = go.Scatter(x=times, y=transactions, mode='lines+markers', name='Transactions per Interval')
67+
68+
layout = go.Layout(
69+
title=f'Métricas de MySQL - Intervalo {interval}',
70+
xaxis=dict(title='Tiempo'),
71+
yaxis=dict(title='Valores'),
72+
hovermode='closest'
73+
)
74+
75+
fig = go.Figure(data=[trace_cpu, trace_memory, trace_transactions], layout=layout)
76+
graph_div = opy.plot(fig, auto_open=False, output_type='div')
77+
78+
# HTML simple con instrucciones y el gráfico interactivo
79+
html = f"""
80+
<html>
81+
<head>
82+
<title>Dashboard MySQL Monitor</title>
83+
<meta name='viewport' content='width=device-width, initial-scale=1'>
84+
</head>
85+
<body>
86+
<h1>Dashboard MySQL Monitor</h1>
87+
<p>Intervalo de datos: {interval}</p>
88+
{graph_div}
89+
<p>Usa el parámetro <code>interval</code> en la URL para cambiar el rango de datos. Ejemplos:</p>
90+
<ul>
91+
<li><a href='/?interval=1h'>Última hora</a></li>
92+
<li><a href='/?interval=6h'>Últimas 6 horas</a></li>
93+
<li><a href='/?interval=24h'>Último día</a></li>
94+
<li><a href='/?interval=30d'>Último mes</a></li>
95+
</ul>
96+
</body>
97+
</html>
98+
"""
99+
return html
100+
101+
102+
if __name__ == '__main__':
103+
# Ejecutar la aplicación en modo debug y en el puerto 5000
104+
app.run(debug=True, host='0.0.0.0', port=5306)

mongo_analytics.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import sys
4+
import json
5+
from dotenv import load_dotenv
6+
from pymongo import MongoClient
7+
8+
# Cargar variables de entorno
9+
load_dotenv()
10+
11+
def generate_report(mongo_uri, exclude_db="sync_status"):
12+
"""
13+
Conecta a MongoDB y genera un reporte con estadísticas básicas de cada base de datos
14+
(excepto la base de sincronización 'sync_status'). Para cada base de datos se listan las
15+
colecciones y se reporta, por ejemplo, la cantidad de documentos.
16+
"""
17+
client = MongoClient(mongo_uri)
18+
report = {}
19+
20+
# Obtener la lista de bases de datos
21+
databases = client.list_database_names()
22+
# Excluir la base usada para almacenar el estado de sincronización
23+
databases = [db for db in databases if db != exclude_db]
24+
25+
for db_name in databases:
26+
db = client[db_name]
27+
collections = db.list_collection_names()
28+
db_report = {}
29+
for coll in collections:
30+
# Usamos estimated_document_count para obtener un conteo rápido
31+
count = db[coll].estimated_document_count()
32+
db_report[coll] = {
33+
"record_count": count
34+
# Aquí podrías agregar otros parámetros, por ejemplo,
35+
# última fecha de actualización si la incluyeras en los documentos,
36+
# tamaño de la colección, etc.
37+
}
38+
report[db_name] = db_report
39+
40+
return report
41+
42+
def main():
43+
# Construir la URI de MongoDB a partir de las variables de entorno
44+
mongo_uri = f"mongodb://{os.getenv('MONGO_USERNAME')}:{os.getenv('MONGO_PASSWORD')}@{os.getenv('MONGO_HOST')}:27017/"
45+
46+
report = generate_report(mongo_uri)
47+
# Imprimir el reporte en formato JSON para facilitar su lectura o procesamiento
48+
print(json.dumps(report, indent=4))
49+
50+
if __name__ == "__main__":
51+
main()

monitor_cron.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#!/usr/bin/env python3
2+
import os
3+
from dotenv import load_dotenv
4+
import sys
5+
import datetime
6+
import json
7+
8+
# Cargar variables de entorno
9+
load_dotenv()
10+
11+
# Se asume que ya tienes la función get_mysql_metrics definida en mysql_monitor.py,
12+
# la cual obtiene las métricas de MySQL y las devuelve como diccionario.
13+
try:
14+
from mysql_monitor import get_mysql_metrics
15+
except ImportError:
16+
sys.exit("No se encontró el módulo mysql_monitor. Asegúrate de tenerlo en tu PYTHONPATH.")
17+
18+
# Intentamos importar pymongo y, si no está instalado, lo instalamos automáticamente.
19+
try:
20+
from pymongo import MongoClient
21+
except ImportError:
22+
import subprocess
23+
subprocess.check_call([sys.executable, "-m", "pip", "install", "pymongo"])
24+
from pymongo import MongoClient
25+
26+
def store_metrics_in_mongodb(metrics, mongo_uri=f"mongodb://{os.getenv('MONGO_USERNAME')}:{os.getenv('MONGO_PASSWORD')}@{os.getenv('MONGO_HOST')}:27017/",
27+
db_name="mysql_monitor", collection_name="metrics"):
28+
"""
29+
Almacena el diccionario de métricas en MongoDB agregándole un timestamp.
30+
"""
31+
client = MongoClient(mongo_uri)
32+
db = client[db_name]
33+
collection = db[collection_name]
34+
35+
# Agregamos el timestamp de la medición (en UTC)
36+
metrics["timestamp"] = datetime.datetime.now(datetime.timezone.utc).timestamp()
37+
38+
# Insertamos el documento en la colección
39+
result = collection.insert_one(metrics)
40+
print(f"Datos almacenados con _id: {result.inserted_id}")
41+
42+
def main():
43+
# Reemplaza estos parámetros según tu configuración de MySQL
44+
host = os.getenv('DB_HOST')
45+
port = os.getenv('DB_PORT')
46+
user = os.getenv('DB_USERNAME')
47+
password = os.getenv('DB_PASSWORD')
48+
49+
# Obtener métricas desde MySQL
50+
metrics = get_mysql_metrics(host=host, port=port, user=user, password=password)
51+
52+
# Almacenar en MongoDB
53+
store_metrics_in_mongodb(metrics)
54+
55+
# También puedes imprimir en JSON para depuración o para redireccionar la salida
56+
print(json.dumps(metrics, indent=4, default=str))
57+
58+
if __name__ == "__main__":
59+
main()

0 commit comments

Comments
 (0)