Skip to content

Repository files navigation

sqlserver-dpa-dashboard

CI License: MIT Python 3.9+ Dependencies: none

Panel de pared para el estado de instancias SQL Server monitorizadas por SolarWinds DPA. Saca las métricas de rendimiento de la REST interna de DPA —la API pública no expone ni una— y las pinta en tres vistas: detalle para el PC, Modo TV para la pantalla de sala y una rotación desatendida. Solo lectura, sin dependencias más allá de la librería estándar de Python.

Wall dashboard for SQL Server instances monitored by SolarWinds DPA. Pulls performance metrics from DPA's internal REST layer — the public API exposes none — and renders them in three views: a detailed desktop view, a TV mode for a wall screen, and an unattended slideshow. Read-only, no dependencies beyond the Python standard library.


Características principales / Features

  • Sin dependencias ni base de datos propia. Un solo python3 dpa.py. DPA ya guarda el histórico, así que /api/historico es una pasarela con caché: las gráficas de 24 h salen llenas desde el primer minuto.
  • Solo lectura. El colector inicia sesión y consulta. Nunca escribe en DPA ni en las instancias monitorizadas.
  • Toda la instalación en dpa.json. Conexión, credenciales, colores, orden de rotación y pie de página se declaran en un fichero. El código no conoce ninguna instancia concreta.
  • Semáforo con los umbrales de DPA, no inventados aquí: se leen los alarmLevel de las nueve categorías (CPU, Memory, Disk, Sessions, Waits, TempDB, Backups, Network, License Compliance).
  • Detalle de bloqueos, con las columnas crudas de sysprocesses: quién bloquea, quién espera, desde qué programa y cuánto lleva.
  • Availability Groups: clúster, salud, réplica primaria, rol, número de réplicas y modo de conmutación.
  • Tres vistas: normal, Modo TV y presentación en rotación automática.
  • Aviso de caída del propio panel: si el navegador pierde el servicio, se superpone un cartel con cronómetro. Una pantalla congelada no se confunde con una sala en verde.

De dónde salen los datos / Where the data comes from

DPA expone dos interfaces HTTP y hacen cosas distintas:

API pública (/iwc/api) REST interna (/iwc/rest)
Autenticación token (refresh → access) cookie de sesión web
Documentada sí (Swagger en /iwc/api-doc) no
Contenido administración: registrar instancias, monitores, alertas, licencias datos de rendimiento

La API pública no expone ni una métrica de rendimiento. Todo lo que pinta este panel viene de la REST interna, a la que el colector accede iniciando sesión con usuario y contraseña, igual que un navegador. Si la sesión caduca, DPA devuelve HTML en vez de JSON; el cliente lo detecta, vuelve a loguearse y reintenta una sola vez.

Endpoints usados

Endpoint Para qué
GET /iwc/rest/databases inventario: id, nombre, tipo, estado del monitor, AG
GET /iwc/rest/databases/{id}/super-tab nivel de Trends, Tuning, salud del AG y Recursos
GET /iwc/rest/databases/{id}/metrics/categories alarmLevel por categoría (el semáforo de DPA)
GET /iwc/rest/databases/{id}/metrics/data series {time, value} de las métricas
GET /iwc/rest/ag-status/summary Availability Group completo

La excepción: las sesiones bloqueadas

El detalle de los bloqueos no existe en ninguna API JSON. La pantalla Current de DPA lo saca de una página HTML normal:

GET /iwc/realTimeTab.iwc?db_id=<id>&action=4&cs=1

Devuelve la tabla de la pestaña Blocking con las columnas de sysprocesses, y el colector la parsea con html.parser.

Es la parte frágil del proyecto: si SolarWinds cambia esa página en una actualización, deja de parsear. Por eso está acotada — solo se pide cuando DPA ya ha dicho que hay sesiones bloqueadas, y va en su propio try: si falla, se registra en el log, la tarjeta sigue viva y simplemente no aparece la lista.

Requisitos previos / Requirements

Python 3.9 o superior (solo librería estándar)
SO Cualquiera para ejecutarlo; el despliegue automático asume Ubuntu con systemd
DPA SolarWinds Database Performance Analyzer accesible por HTTP/HTTPS
Cuenta Un usuario de DPA de solo lectura, dedicado a este panel
Red Acceso del servidor al puerto de DPA (8124/tcp con HTTPS, 8123/tcp con HTTP)

Instalación / Installation

Prueba rápida / Quick start

git clone https://github.com/mr7security/sqlserver-dpa-dashboard.git
cd sqlserver-dpa-dashboard
cp dpa.json.example dpa.json     # edita url, usuario y password
python3 dpa.py

Abre http://localhost:9000. Sin un DPA real detrás el panel arranca igualmente y muestra el aviso de sin conexión: sirve para ver la interfaz.

Despliegue en Ubuntu / Deploy on Ubuntu

git clone https://github.com/mr7security/sqlserver-dpa-dashboard.git ~/sqlserver-dpa-dashboard
cd ~/sqlserver-dpa-dashboard
sudo bash deploy.sh
sudo nano /opt/sqlserver-dpa-dashboard/dpa.json
sudo systemctl restart sqlserver-dpa-dashboard

Instala en /opt/sqlserver-dpa-dashboard, crea el usuario de servicio dpadash (sin shell y sin home) y deja dpa.json en modo 640. El servicio corre sin privilegios, así que el puerto tiene que ser ≥ 1024.

Actualizar es git pull && sudo bash deploy.sh. No pisa dpa.json.

Uso / Usage

Configuración

Todo vive en dpa.json (copia de dpa.json.example):

{
  "url": "https://192.0.2.10:8124",
  "usuario": "CAMBIAME",
  "password": "CAMBIAME",
  "verificar_ssl": false,
  "puerto": 9000,
  "intervalo_segundos": 30,
  "listar_sesiones_activas": true,
  "ui": {
    "titulo": "Estado de bases de datos",
    "pie": "DEPARTAMENTO IT",
    "colores_servidor": { "DB-01": "#38bdf8", "DB-02": "#818cf8" },
    "alias_tv": { "SRV-05 via CLUSTER-LARGO": "DB-05" },
    "orden_presentacion": ["DB-01", "DB-02", "DB-03"]
  }
}

Los colores se eligen fuera de la gama del semáforo (verde/ámbar/rojo) para que nunca se confundan con una alarma. Las instancias que no aparezcan en orden_presentacion se añaden al final por orden alfabético: registrar una nueva en DPA no obliga a tocar nada aquí.

Las tres vistas

Vista Para qué Qué muestra
Normal mirar desde el PC una instancia por fila, a todo el ancho: métricas y medidores, detalle y AG, gráficas y disco. Debajo, bloqueos y sesiones activas
Modo TV pantalla de sala todas las instancias a la vez, solo sesiones e indicadores, con un panel de bloqueos abajo
Presentación rotación desatendida alterna la vista general con cada instancia a pantalla completa, cada 15 s (30 s si está en crítico)

Controles en presentación: flechas para moverse, espacio para pausar, Esc para salir, y clic en cualquier nombre de la tira superior para saltar ahí.

Semáforo

Nivel Cuándo
caido monitor de DPA parado, o sin respuesta
critico alguna categoría en CRITICAL, Tuning/AG en CRITICAL, o ≥ 5 sesiones bloqueadas
aviso alguna categoría en WARNING, o 1-4 sesiones bloqueadas
ok resto

API

Ruta Devuelve
/ el dashboard
/api/estado instantánea completa en JSON
/api/historico?db=<id>&metrica=<nombre>&horas=<n> serie histórica
/api/config solo el bloque ui: nunca expone conexión ni credenciales
/logo logotipo opcional, si dejas un logo.* junto a dpa.py

Solo se aceptan métricas de la lista blanca del colector.

Diagnóstico

journalctl -u sqlserver-dpa-dashboard -f
sudo -u dpadash python3 /opt/sqlserver-dpa-dashboard/dpa.py --once | sed -n '/^{/,$p'

--once mezcla los logs con el JSON, de ahí el sed.

Estructura del proyecto / Project structure

sqlserver-dpa-dashboard/
├── dpa.py                             colector, API y servidor HTTP (stdlib)
├── dpa.html                           interfaz completa, autocontenida
├── dpa.json.example                   plantilla de configuración
├── deploy.sh                          instalación/actualización en Ubuntu
├── sqlserver-dpa-dashboard.service    unidad systemd endurecida
├── ruff.toml                          reglas de lint
├── .github/workflows/ci.yml           lint, compilación y control de secretos
├── LICENSE
└── README.md

Ficheros que no se versionan: dpa.json y el logo.* corporativo.

Seguridad / Security

  • dpa.json contiene usuario y contraseña de DPA. Está en .gitignore, deploy.sh lo deja en modo 640 y el CI falla si aparece en el repositorio.
  • Usa un usuario de DPA dedicado y de solo lectura, nunca dpaADMIN.
  • Prefiere HTTPS (8124). Con HTTP (8123) la contraseña viaja en claro por la red.
  • El servicio corre como usuario sin privilegios (dpadash), con ProtectSystem=strict, NoNewPrivileges y RestrictSUIDSGID.
  • El panel no tiene autenticación: publícalo solo en la VLAN de gestión, o detrás de un proxy inverso que la añada.
  • /api/config expone únicamente el bloque de presentación. Los nombres de instancia salen en /api/estado — un motivo más para no exponer el puerto.

Contribución / Contributing

Las incidencias y las pull request son bienvenidas. Antes de abrir una PR:

pip install ruff
ruff check dpa.py
python -m py_compile dpa.py

Los commits siguen Conventional Commits: feat:, fix:, docs:, refactor:, chore:.

Licencia / License

MIT — ver LICENSE.

About

Wall dashboard for SQL Server instances monitored by SolarWinds DPA — sessions, blocking, waits and Availability Groups from DPA's internal REST layer. Read-only, config-driven, Python standard library only.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages