
monitor v0.34.0
Monitoreo en tiempo real y análisis de slowlog para bases de datos Valkey y Redis con detección de anomalías, auditoría de ACL y exportación de métricas a Prometheus.
BetterDB Monitor
La capa de monitoreo que Valkey se merece.
BetterDB persiste lo que Valkey descarta: slowlogs, patrones de comandos, actividad de clientes, señales de anomalías, para que puedas depurar lo que ocurrió a las 3 a. m., no solo lo que está ocurriendo ahora. Diseñado para Valkey 8.x con soporte nativo para COMMANDLOG, CLUSTER SLOT-STATS y métricas de I/O por hilo. Compatible con Redis 6+ para todo lo demás.
Website | Docker Hub | npm | Documentation | Blog
BetterDB está desarrollado por BetterDB Inc., una empresa de beneficio público que opera bajo la OCV Open Charter.

Inicio rápido (Docker)```bash
docker run -d --name betterdb -p 3001:3001 betterdb/monitor:latest
Apunta tu navegador a `http://localhost:3001`. Para monitorear una instancia específica:```bash
docker run -d \
--name betterdb \
-p 3001:3001 \
-e DB_HOST=your-valkey-host \
-e DB_PORT=6379 \
-e DB_PASSWORD=your-password \
betterdb/monitor:latest
¿Conectándote a una base de datos en tu máquina host? Dentro del contenedor,
localhostes el propio contenedor, no tu host — así que usahost.docker.internalcomo host de la base de datos. En Docker Desktop (macOS/Windows) funciona sin configuración adicional; en Linux añade--add-host=host.docker.internal:host-gatewayal comandodocker runpara que el nombre se resuelva. El botón de "conectar a instancia local" con un clic del panel detecta esto automáticamente y rellena el host correcto por ti.
Se publican dos variantes de imagen, ambas multi-arquitectura (linux/amd64, linux/arm64):
| Etiqueta | Qué es |
|---|---|
latest, X.Y.Z-no-ai | Imagen predeterminada: incluye todas las funciones de monitoreo, sin las dependencias para el Asistente de IA local-LLM experimental |
X.Y.Z | Añade el Asistente de IA experimental (trae tu propio Ollama; deshabilitado por defecto mediante AI_ENABLED) |
Consulta Implementación de producción con Docker para almacenamiento persistente, puertos personalizados, licencias y configuraciones aisladas de red.
Inicio rápido (Kubernetes / Helm)```bash
helm repo add betterdb https://docs.betterdb.com/charts
helm repo update
helm install betterdb-monitor betterdb/betterdb-monitor
--namespace betterdb --create-namespace
--set db.host=my-valkey.default.svc.cluster.local
--set db.password=yourpassword
Entonces ejecuta `kubectl port-forward -n betterdb svc/betterdb-monitor 3001:3001` y abre `http://localhost:3001`, o habilita el ingress del chart. El historial respaldado por PostgreSQL, los Secrets traídos por el usuario y las licencias en entornos aislados (air-gapped) están cubiertos en la [guía de Kubernetes](https://docs.betterdb.com/kubernetes) y en el [README del chart](https://github.com/betterdb-inc/monitor/blob/master/charts/betterdb-monitor/README.md).
## Inicio rápido (CLI)
Ejecuta BetterDB Monitor sin Docker:```bash
npx @betterdb/monitor
En la primera ejecución, un asistente de configuración interactivo te guía a través de la conexión a la base de datos, el backend de almacenamiento (SQLite, PostgreSQL o en memoria) y la configuración del servidor. La configuración se guarda en ~/.betterdb/config.json.```bash
npm install -g @betterdb/monitor # global install
betterdb --setup # re-run setup wizard
betterdb --port 8080 # override server port
betterdb --db-host 1.2.3.4 # override database host
betterdb --help # all options
Requiere Node.js >= 20.0.0 y una instancia de Valkey o Redis para monitorear. Para almacenamiento SQLite, también `npm install -g better-sqlite3`.
## Lo que obtienes
### Ve todo, conserva todo
- **Analíticas históricas** - consulta slowlogs, patrones de comandos, actividad de clientes y latencia en cualquier rango de tiempo. Los datos que solían desaparecer tras una rotación de logs.
- **Soporte de COMMANDLOG** - exclusivo de Valkey 8.1+. Solicitudes grandes y respuestas grandes, no solo las lentas.
- **Sesiones de captura MONITOR** - graba tráfico real bajo demanda: seguimiento en vivo, filtrado, reproducción, exportación a JSON/CSV y referencias cruzadas contra el historial de conexiones.
- **Seguimiento de claves calientes** - claves principales por frecuencia de acceso con movimiento de rango a lo largo del tiempo. Key Analytics (Pro, gratis en acceso anticipado) añade distribuciones de tipo, TTL y tamaño a partir de muestreo en vivo.
- **Visibilidad de clúster** - gráficos de topología, mapas de calor SLOT-STATS, CPU por slot y distribución de claves.
- **Métricas de CPU y subprocesos de E/S** - visibilidad por subproceso que ninguna herramienta de Redis puede ofrecer.
- **Analíticas de clientes** - ve exactamente qué servicio es responsable de qué, atribuido por nombre de cliente y patrón.
- **Registro de auditoría ACL** - rastrea quién accedió a qué, persistido para cumplimiento normativo y depuración posterior a incidentes.
### Comprende y actúa
- **Detección de anomalías** (Pro, gratis en acceso anticipado) - aprendizaje automático de línea base con eventos correlacionados y diagnósticos en lenguaje sencillo. Más de 20 detectores, sin umbrales manuales.
- **Previsión de capacidad** - tiempo proyectado hasta el límite para memoria, ops/seg, CPU y fragmentación.
- **Webhooks** - entregas de alertas firmadas con HMAC con reintentos y un registro completo de entregas.
- **Migración en vivo** - muévete entre Redis y Valkey con un flujo de trabajo de análisis, ejecución y validación en tres fases.
### Diseñado para la era de la IA
- **Observabilidad de búsqueda vectorial** - ops/seg y latencia de FT.SEARCH con salud por índice para [valkey-search](https://github.com/valkey-io/valkey-search) y RediSearch. Consulta [docs/vector-ai](https://github.com/betterdb-inc/monitor/blob/master/docs/vector-ai/README.md).
- **Latencia de inferencia** - p50/p95/p99 por índice, con alertas de incumplimiento de SLA (Pro, gratis en acceso anticipado).
- **Inteligencia de caché semántica** (Pro, gratis en acceso anticipado) - salud de tasa de aciertos, recomendaciones de umbral de similitud y un flujo de trabajo de propuestas aprobar/rechazar. Observabilidad de memoria de agentes incluida.
- **Trazas de IA** - cascadas de spans OTLP desde tu aplicación de IA, correlacionadas con el estado en vivo de Valkey debajo de cada solicitud.
### Se integra con todo
- **Servidor MCP** - 60 herramientas para Claude Code, Cursor o cualquier cliente MCP mediante [`@betterdb/mcp`](https://github.com/betterdb-inc/monitor/blob/master/packages/mcp).
- **Endpoint Prometheus** - más de 100 métricas `betterdb_*`. Consulta [docs/prometheus-metrics.md](https://github.com/betterdb-inc/monitor/blob/master/docs/prometheus-metrics.md).
- **OpenTelemetry** - replica métricas y eventos a cualquier backend OTLP.
- **API REST** - todo en la interfaz es una llamada API, documentada mediante OpenAPI.
## Accede a tus datos a tu manera
| Interfaz | Detalles |
|-----------|---------|
| Interfaz web | `http://localhost:3001` |
| Servidor MCP | `npx @betterdb/mcp` (stdio) - crea un token en Configuración → Tokens MCP |
| Prometheus | `http://localhost:3001/api/prometheus/metrics` |
| API REST (OpenAPI) | `http://localhost:3001/docs` |
| Verificación de salud | `http://localhost:3001/api/health` |
> **Nota**: En compilaciones de producción (Docker, CLI) las rutas de API se sirven bajo el prefijo `/api`. En desarrollo local (`pnpm dev`) no hay prefijo - p. ej. `http://localhost:3001/health`.
## Bases de datos compatibles
| Base de datos | Versión mínima | Funciones compatibles |
|----------|----------------|-------------------|
| **Valkey** | 8.0+ | Todas las funciones, incluidos COMMANDLOG (8.1+) y CLUSTER SLOT-STATS |
| **Redis** | 6+ | Todas las funciones excepto COMMANDLOG y CLUSTER SLOT-STATS, exclusivos de Valkey |
El backend utiliza un adaptador unificado sobre el cliente `iovalkey` compatible por cable y detecta automáticamente Valkey vs Redis a partir de la respuesta `INFO` (`DB_TYPE=auto`). Capacidades como COMMANDLOG y SLOT-STATS se detectan por versión, y la interfaz degrada con elegancia cuando una función no está disponible.
Los servicios gestionados también son compatibles - las guías para AWS ElastiCache, MemoryDB, Redis Cloud y Upstash se encuentran en [docs/providers](https://github.com/betterdb-inc/monitor/blob/master/docs/providers), y [`@betterdb/agent`](https://github.com/betterdb-inc/monitor/blob/master/packages/agent) alcanza instancias solo-VPC mediante un WebSocket saliente.
## Implementación de producción con Docker
La imagen de Docker contiene la aplicación de monitoreo (backend + frontend). Requiere:
1. Una instancia de Valkey/Redis para monitorear
2. Una instancia de PostgreSQL para la persistencia de datos (o usa almacenamiento en memoria)
### Ejecutar con almacenamiento PostgreSQL```bash
docker run -d \
--name betterdb-monitor \
-p 3001:3001 \
-e DB_HOST=your-valkey-host \
-e DB_PORT=6379 \
-e DB_PASSWORD=your-password \
-e STORAGE_TYPE=postgres \
-e STORAGE_URL=postgresql://user:pass@postgres-host:5432/dbname \
betterdb/monitor
Ejecutar en un puerto personalizado
Establece la variable de entorno PORT y haz coincidir el mapeo -p:```bash
docker run -d
--name betterdb-monitor
-p 8080:8080
-e PORT=8080
-e DB_HOST=your-valkey-host
betterdb/monitor
### Ejecutar con red del host (acceder a servicios localhost)
Si tu Valkey y PostgreSQL se están ejecutando en el mismo host:```bash
docker run -d \
--name betterdb-monitor \
--network host \
-e DB_HOST=localhost \
-e DB_PORT=6380 \
-e DB_PASSWORD=devpassword \
-e STORAGE_TYPE=postgres \
-e STORAGE_URL=postgresql://dev:devpass@localhost:5432/postgres \
betterdb/monitor
Variables de Entorno
| Variable | Requerida | Valor por defecto | Descripción |
|---|---|---|---|
DB_HOST | Sí | localhost | Host de Valkey/Redis a monitorear |
DB_PORT | No | 6379 | Puerto de Valkey/Redis |
DB_PASSWORD | No | - | Contraseña de Valkey/Redis |
DB_USERNAME | No | default | Nombre de usuario ACL de Valkey/Redis |
DB_TYPE | No | auto | Tipo de base de datos: auto, valkey o redis |
STORAGE_TYPE | No | memory | Backend de almacenamiento: memory o postgres |
STORAGE_URL | Condicional | - | URL de conexión de PostgreSQL (requerida si STORAGE_TYPE=postgres) |
PORT | No | 3001 | Puerto HTTP de la aplicación |
NODE_ENV | No | production | Entorno de Node |
ANOMALY_DETECTION_ENABLED | No | true | Habilitar detección de anomalías |
ANOMALY_PROMETHEUS_INTERVAL_MS | No | 30000 | Intervalo de actualización del resumen de Prometheus (ms) |
BETTERDB_LICENSE_KEY | No | - | Clave de licencia en línea (Pro/Enterprise), validada a través de la red |
BETTERDB_OFFLINE_LICENSE_FILE | No | - | Ruta a una licencia sin conexión firmada .jwt para hosts aislados de la red (ver más abajo) |
BETTERDB_OFFLINE_LICENSE | No | - | Token de licencia sin conexión como cadena JWT en línea |
BETTERDB_DATA_DIR | No | /app/data | Directorio para el estado de licencia persistido (montar un volumen con escritura) |
ENCRYPTION_KEY | No | - | Clave (mínimo 16 caracteres) utilizada para cifrar en reposo mediante sobreenvoltura las contraseñas de conexión almacenadas y los secretos de túneles SSH. Sin ella, los secretos se almacenan en texto plano |
BETTERDB_SSH_KEY_DIR | No | - | Directorio en el que deben residir las claves privadas SSH del lado del servidor. Habilita la fuente de claves "ruta de archivo del servidor" para túneles SSH; la ruta de la clave de una conexión debe resolverse dentro de él. Si no se define, se deshabilitan las claves basadas en archivos (las claves pegadas en línea siguen funcionando) |
BETTERDB_TELEMETRY | No | true | Establecer false para deshabilitar la telemetría anónima |
Referencia completa, incluidos IA, exportación OTLP, ajuste de webhooks y umbrales de compuerta de salud: docs/configuration.md.
Túneles SSH
Las conexiones pueden llegar a una base de datos a través de un host bastión/salto SSH en lugar de conectarse directamente — útil para Valkey/Redis en una subred privada, ElastiCache o MemoryDB. Habilite Conectar mediante túnel SSH al agregar una conexión y proporcione el host, puerto y nombre de usuario SSH. Se admite un solo salto.
La autenticación es mediante contraseña o clave privada. Las claves privadas provienen de una de dos fuentes:
- Pegar clave (en línea): el contenido de la clave PEM se envía con la conexión. Se almacena cifrada en reposo solo cuando
ENCRYPTION_KEYestá definida (cifrado por sobreenvoltura); sin esa clave se almacena en texto plano, al igual que las contraseñas de conexión. Funciona en todas partes, incluidas implementaciones administradas/en la nube. - Ruta de archivo del servidor: la clave ya reside en el sistema de archivos del servidor de monitoreo y se referencia por ruta. Esto requiere definir la variable de entorno
BETTERDB_SSH_KEY_DIRal directorio que contiene las claves permitidas, y la ruta referenciada debe resolverse dentro de él, de modo que la API nunca pueda ser forzada a leer archivos arbitrarios. DejeBETTERDB_SSH_KEY_DIRsin definir para deshabilitar esta opción.
Opcionalmente, fije la huella digital de la clave de host del servidor SSH (SHA256:...) en la conexión; cuando se define, el túnel se rechaza a menos que el servidor presente una clave coincidente, lo que previene ataques de intermediario en la ruta del bastión. Si se deja en blanco, la identidad del servidor no se verifica (se registra una advertencia).
El túnel reenvía a la base de datos a través de 127.0.0.1; cuando TLS está habilitado, el certificado aún se valida contra el nombre de host real de la base de datos. Defina ENCRYPTION_KEY para que las contraseñas SSH, frases de contraseña de claves y claves en línea se cifren en reposo.
Limitación conocida — topologías de clúster/Sentinel: solo la conexión que configure se tuneliza. El monitoreo de clúster y Sentinel se expande a los otros nodos utilizando las direcciones que esos nodos anuncian (CLUSTER NODES / Sentinel), y esas conexiones por nodo se realizan directamente, no a través del túnel. Si los otros nodos solo son accesibles a través del bastión (p. ej., ElastiCache/MemoryDB en una subred privada), las vistas por nodo no estarán disponibles. Use túneles SSH para monitoreo de nodo único/principal, o coloque el monitor donde pueda alcanzar los nodos del clúster directamente.
Licencias y soporte para entornos aislados de la red
BetterDB Monitor desbloquea las funciones Pro/Enterprise de una de dos maneras, según si el host tiene acceso a internet:
- Clave de licencia en línea - defina
BETTERDB_LICENSE_KEY. El monitor la valida contrabetterdb.comy almacena en caché un token firmado verificado localmente, de modo que su nivel siga funcionando durante cortes breves y reinicios. - Token de licencia sin conexión / aislado de la red - para hosts sin acceso a internet en absoluto (ver más abajo).
Cómo funciona la licencia en entornos aislados de la red
Cada derecho es un JWT RS256 firmado. El monitor lo verifica localmente contra claves públicas integradas en la imagen — nunca necesita contactar un servidor de licencias para confiar en un token. Así, un host aislado de la red puede ejecutar niveles de pago con cero conectividad:
- En una máquina con conexión a internet, inicie sesión en
betterdb.com/account/licenses y
descargue su token de licencia sin conexión (
.jwt, Pro/Enterprise). No contiene secretos y no puede ser manipulado — cualquier edición rompe la firma. - Transfiéralo al host aislado de la red como prefiera (USB, gestión de configuración, un montaje de secreto de Docker/Kubernetes).
- Provéalo mediante
BETTERDB_OFFLINE_LICENSE_FILE(ruta),BETTERDB_OFFLINE_LICENSE(cadena en línea), o péguelo en la interfaz en Configuración → Licencia → "¿Entorno aislado de la red? Active una licencia sin conexión."
Cuando se configura un token sin conexión y no se define BETTERDB_LICENSE_KEY, el
monitor realiza cero solicitudes salientes — las verificaciones de licencia, la
telemetría y los pings de actualización están todos deshabilitados. Ejecuta el nivel
otorgado hasta que el token expire (las licencias perpetuas se vuelven a descargar
anualmente), luego revierte a Community.```bash
fully offline - no network required
docker volume create betterdb-data docker run --rm -v betterdb-data:/d alpine chown 1001:1001 /d # volume writable by UID 1001 (one-time)
docker run -d --name betterdb-monitor -p 3001:3001
-e DB_HOST=your-valkey-host -e DB_PORT=6379 -e DB_PASSWORD=your-password
-v /path/to/betterdb-license.jwt:/run/secrets/betterdb-license.jwt:ro
-e BETTERDB_OFFLINE_LICENSE_FILE=/run/secrets/betterdb-license.jwt
-v betterdb-data:/app/data
betterdb/monitor
Verifica con `GET /api/license/status` → `source: offline-token`, `mode: offline`,
`airGapped: true`.
> **Persistencia:** monta un volumen con permisos de escritura en `/app/data` para que la licencia offline y
> el token de gracia por caída en línea sobrevivan a los reinicios. El contenedor se ejecuta como **UID 1001**,
> por lo que un volumen recién creado debe ser `chown`ed a ese usuario (como se muestra arriba); de lo contrario,
> la persistencia falla con `EACCES … license.jwt`.
Para el flujo completo, la precedencia de verificación y el runbook de rotación de claves, consulta
**[Licencias Offline y Air-Gapped](https://github.com/betterdb-inc/monitor/blob/master/docs/offline-licenses.md)** y la
**[Referencia de configuración](https://github.com/betterdb-inc/monitor/blob/master/docs/configuration.md#license-configuration)**.
### Detalles de la Imagen Docker
- **Imagen base**: `node:20-alpine`
- **Tamaño comprimido**: ~360MB (`latest` / `-no-ai`) / ~640MB (imagen versionada con las dependencias de LLM local del AI Helper experimental)
- **Plataformas**: `linux/amd64`, `linux/arm64`
- **Contiene**: API backend + archivos estáticos del frontend (servidos por Fastify)
- **Excluye**: soporte de SQLite (usa PostgreSQL o almacenamiento en memoria)
### Operaciones del Contenedor```bash
docker logs -f betterdb-monitor # follow logs
docker stop betterdb-monitor # stop
docker rm betterdb-monitor # remove
Backends de Almacenamiento
BetterDB Monitor persiste el registro de auditoría, análisis, capturas y datos de anomalías en uno de tres backends:
| Backend | Caso de uso | Notas |
|---|---|---|
memory | Pruebas, entornos efímeros | Predeterminado en Docker; todos los datos se pierden al reiniciar |
postgres | Producción | STORAGE_TYPE=postgres + STORAGE_URL=postgresql://user:pass@host:port/db |
sqlite | Desarrollo local / CLI | No incluido en las imágenes de producción de Docker; STORAGE_SQLITE_FILEPATH opcional |
Métricas de Prometheus
Las métricas se exponen en GET /api/prometheus/metrics en formato de texto de Prometheus: auditoría de ACL, conexiones de clientes, patrones de slowlog/commandlog, memoria, rendimiento, keyspace, replicación, estadísticas de slots de clúster y métricas de runtime de Node.js — todas con el prefijo betterdb_.```yaml
scrape_configs:
- job_name: 'betterdb-monitor'
metrics_path: '/api/prometheus/metrics'
static_configs:
- targets: ['your-monitor-host:3001']
Referencia completa de métricas: [docs/prometheus-metrics.md](https://github.com/betterdb-inc/monitor/blob/master/docs/prometheus-metrics.md) y [docs/prometheus-integration.md](https://github.com/betterdb-inc/monitor/blob/master/docs/prometheus-integration.md).
## Desarrollo
### Estructura del Proyecto```
betterdb-monitor/
├── apps/
│ ├── api/ # NestJS backend (Fastify)
│ └── web/ # React frontend (Vite)
├── packages/ # Published packages (see below)
├── docs/ # Documentation site (Jekyll)
├── docker-compose.yml # Local Valkey (port 6380) and Redis (port 6382) for testing
└── package.json # Workspace root
Paquetes
Este monorepo incluye varios paquetes independientes. Consulta packages/ para ver la lista completa.
| Paquete | Lenguaje | Registro |
|---|---|---|
@betterdb/monitor | TypeScript | npm |
@betterdb/mcp | TypeScript | npm |
@betterdb/agent | TypeScript | npm |
@betterdb/semantic-cache | TypeScript | npm |
betterdb-semantic-cache | Python | PyPI |
@betterdb/agent-cache | TypeScript | npm |
betterdb-agent-cache | Python | PyPI |
cache-benchmark | Python | Harness de reproducción para evaluar el rendimiento de cachés semánticas |
Pila Tecnológica
- Backend: NestJS con adaptador Fastify,
iovalkeypara conexiones Valkey/Redis, modo estricto de TypeScript. Puerto 3001. - Frontend: React + TypeScript, Vite, TailwindCSS, Recharts. Servidor de desarrollo en el puerto 5173.
- Monorepo: pnpm workspaces + Turborepo.
Configuración Local
Requisitos previos: Node.js >= 20.0.0, pnpm >= 9.0.0, Docker.```bash pnpm install cp .env.example .env pnpm docker:dev # local Valkey (6380) and Redis (6382) pnpm dev # web on :5173, api on :3001
Para conectarse a Redis en lugar de Valkey, establezca `DB_PORT=6382` en `.env`.```bash
pnpm dev:api # API only
pnpm dev:web # frontend only
pnpm docker:dev:down # stop local databases
pnpm build # production build
pnpm test # API tests
Docker image builds:```bash pnpm docker:build # local build pnpm docker:publish # multi-arch build & push (requires buildx)
### Añadir Nuevas Funcionalidades
1. Añade nuevos endpoints en `apps/api/src/`
2. Añade las llamadas API correspondientes en `apps/web/src/api/`
3. Añade los tipos compartidos en `packages/shared/src/types/`
### Estilo de Código
- Modo estricto de TypeScript, tipos de retorno explícitos, sin `any`
- ESLint + Prettier configurados
## Licencia
- El contenido bajo `docs/` está licenciado bajo CC BY-SA 4.0.
- El contenido bajo `proprietary/` está cubierto por una licencia comercial (consulta `proprietary/LICENSE`). Estas funcionalidades son gratuitas durante el acceso anticipado.
- Todo lo demás está bajo [MIT](https://github.com/betterdb-inc/monitor/blob/master/LICENSE).