====== Resumen del Proyecto ======
Este documento resume malísimamente los pasos y desarrollos realizados hasta la fecha en el proyecto de monitoreo y registro de eventos para hosts y Backup Vaults.
=== 1. Creación de Tablas por Host/Backup Vault ===
* Se configuró la aplicación para que, al recibir datos, cree dinámicamente una tabla para cada host o Backup Vault si no existe.
* Cada tabla individual almacena los siguientes campos:
* `id`: INT, AUTO_INCREMENT, PRIMARY KEY
* `creationtime`: `VARCHAR(255)` - Hora de creación en formato cadena.
* `vmname`: `VARCHAR(255)` - Nombre de la VM o recurso.
* `type`: `VARCHAR(255)` - Tipo de tarea.
* `result`: `VARCHAR(255)` - Resultado de la tarea.
* `detail`: `TEXT` - Detalles adicionales.
----
=== 2. Implementación de Nuevas Columnas para Timestamps ===
* Se agregó una columna adicional `datetime` a las tablas por host.
* Esta columna almacena el tiempo de creación (`creationtime`) en formato `DATETIME`, estandarizando las fechas para facilitar futuras consultas y análisis.
* Se implementó un script para procesar y convertir los diferentes formatos de fecha/hora recibidos al formato `DATETIME`.
----
=== 3. Autenticación en la API ===
* Se añadió un mecanismo básico de autenticación por token en el endpoint `/upload`.
* Solo se permite la carga de datos si el token es válido.
====== Azure Backup Vault Monitoring API ======
This project consists of a Python Flask API that receives data from an Azure Automation Runbook about backup jobs in an Azure Backup Vault. The API processes this data and inserts it into a MariaDB database.
===== How It Works =====
1. **Azure Automation Runbook**:
- Connects to Azure using Managed Identity.
- Retrieves the latest backup jobs from the specified Azure Backup Vault.
- Sends this data as a JSON payload to the Flask API.
2. **Flask API**:
- Receives the JSON payload from the Automation Runbook.
- Parses the `hostname` and `restorePoints` from the JSON.
- Inserts the backup job data into a dynamically created table in the MariaDB database.
===== Powershell Script =====
The Powershell script retrieves the backup jobs and sends them to the Flask API. Here is a simplified overview:
# Login to Azure (Using Managed Identity)
Connect-AzAccount -Identity
# Get backup jobs from the last 24 hours
$vault = Get-AzRecoveryServicesVault
$backupJobs = Get-AzRecoveryServicesBackupJob -VaultId $vault.ID -From (Get-Date).AddDays(-1).ToUniversalTime()
# Prepare the API request
$uri = "https://api.facundoitest.space/upload"
$headers = @{
"Content-Type" = "application/json"
"Authorization" = "bXktbG9----LongAssBase64String----XN0cmluZw=="
}
# Create the JSON payload
$backupJobsList = $backupJobs | ForEach-Object {
[PSCustomObject]@{
"vmname" = $_.WorkloadName
"creationtime" = $_.StartTime.ToString("o")
"type" = $_.Operation
"result" = $_.Status
}
}
$body = @{
"hostname" = $vault.Name
"restorePoints" = $backupJobsList
} | ConvertTo-Json -Depth 4
# Send the JSON to the API
$response = Invoke-WebRequest -Uri $uri -Method Post -Body $body -Headers $headers -SkipHeaderValidation
===== Python Flask API =====
The Python API processes the incoming JSON payload and stores the relevant data in MariaDB. Below is **an outline** of the core logic:
from flask import Flask, request, jsonify
import mysql.connector
app = Flask(__name__)
@app.route('/upload', methods=['POST'])
def upload_data():
data = request.get_json()
hostname = data.get('hostname')
restore_points = data.get('restorePoints')
conn = mysql.connector.connect(host='db_host', user='db_user', password='db_password', database='VeeamReports')
cursor = conn.cursor()
table_name = f"{hostname}_backups"
create_table_query = f\"\"\"
CREATE TABLE IF NOT EXISTS {table_name} (
id INT AUTO_INCREMENT PRIMARY KEY,
vmname VARCHAR(255),
creationtime DATETIME,
type VARCHAR(255),
result VARCHAR(255)
)
\"\"\"
cursor.execute(create_table_query)
for restore_point in restore_points:
vmname = restore_point.get('vmname')
creationtime = restore_point.get('creationtime')
type = restore_point.get('type')
result = restore_point.get('result')
insert_query = f\"\"\"INSERT INTO {table_name} (vmname, creationtime, type, result)
VALUES (%s, %s, %s, %s)\"\"\"
cursor.execute(insert_query, (vmname, creationtime, type, result))
conn.commit()
cursor.close()
conn.close()
return jsonify({"status": "success"}), 200
This setup allows you to monitor your Azure Backup Vault and store backup job data for further analysis or reporting.
----
=== 4. Filtrado de Eventos No Exitosos ===
* Se implementó una lógica para filtrar los eventos con resultados diferentes a 'Success'.
* Estos eventos se almacenan en una tabla central llamada `unsuccessful_tasks`.
* El objetivo de esta tabla es permitir la generación de reportes que muestren la frecuencia y distribución de fallos en los últimos 30 días.
====== Guardado de eventos no exitosos ======
=== 1. Diseño de la Tabla `unsuccessful_tasks` ===
* **Columnas**:
* `id`: INT, AUTO_INCREMENT, PRIMARY KEY
* `creationtime`: `DATETIME` - Timestamp del evento.
* `hostname`: `VARCHAR(255)` - El nombre del host o Backup Vault.
* `vmname`: `VARCHAR(255)` - El nombre de la VM o recurso.
* `type`: `VARCHAR(255)` - El tipo de tarea (e.g., Backup, Snapshot).
* `result`: `VARCHAR(255)` - El resultado (e.g., Fail, Warn).
* `detail`: `TEXT` - Detalles adicionales del evento.
=== 2. Proceso de Inserción de Datos ===
* **Filtrado de Eventos No Exitosos**:
* Cada vez que se registre un evento en las tablas por host, la aplicación debe revisar el campo `result`. Si el valor no es 'Success' o el equivalente en Azure, se inserta un registro en `unsuccessful_tasks`.
* **Job Automático de Monitoreo**:
* Un script de Python podría ejecutarse cada 4 horas para:
* Conectar a las tablas de cada host y revisar nuevos registros.
* Filtrar los eventos no exitosos (`result != 'Success'`).
* Insertar estos eventos en `unsuccessful_tasks`, eliminando cualquier duplicado que ya exista en esa tabla.
* Mantener un historial de 30 días y eliminar registros más antiguos para mantener la tabla manejable.
=== 3. Consultas y Reportes ===
* **Reporte de Frecuencia de Fallos**:
* Crear una consulta que filtre por `hostname` y/o `vmname` para contar cuántas veces se ha registrado un fallo o advertencia en los últimos X días.
* Este reporte es útil para identificar patrones de fallos o problemas recurrentes.
=== 4. Mantenimiento ===
* **Limpieza Regular**:
* Programar un job que elimine registros más antiguos de 30 días (o el período que se decida), para mantener la tabla `unsuccessful_tasks` ligera y rápida en sus consultas.
----
=== 5. Desarrollo de Script de Monitoreo Automático ===
* Se diseñó un job en Python que se ejecuta cada 4 horas.
* Este script realiza las siguientes tareas:
* Filtrar eventos no exitosos de las tablas por host.
* Insertar estos eventos en la tabla `unsuccessful_tasks`.
* Eliminar registros duplicados o más antiguos de 30 días.
----
=== 6. Optimización de Consultas y Mantenimiento ===
* Se establecieron planes para la limpieza regular de la tabla `unsuccessful_tasks` para mantener su eficiencia.
* Además, se consideró la creación de reportes específicos para detectar patrones de fallos.
----
=== 7. Próximos Pasos ===
* Integrar más controles de calidad y validación de datos.
* Optimizar el rendimiento de la base de datos para manejar grandes volúmenes de eventos.
* Expandir la lógica de filtrado para incluir otros tipos de eventos importantes.
----
├── demoBackups
│ ├── app.py
│ ├── static
│ │ └── styles.css
│ └── templates
│ ├── admin.html
│ ├── client_status.html
│ └── index.html