docs: documentar plan de métricas y conjunto core v1

Co-authored-by: aider (openrouter/openai/gpt-5.1) <aider@aider.chat>
main
borja 4 weeks ago
parent 9883af5d02
commit fcf46cdd45

@ -0,0 +1,355 @@
# Plan de métricas del bot
Este documento recoge:
1. Inventario de las métricas **ya existentes** en el código.
2. Clasificación de cada métrica:
- **core**: queremos cuidarla y mantenerla estable.
- **nice-to-have**: útil, pero no crítica; se puede ajustar.
- **debug**: orientada a depuración / exploración.
- **dudosa**: probablemente haya que redefinirla o eliminarla.
3. Propuesta de **set “core v1”** (existentes + nuevas).
4. Notas sobre **persistencia** y derivación desde BD.
5. Próximos pasos para implementación.
---
## 1. Inventario actual de métricas
> Nota: solo se listan métricas usadas en código de producción (no tests ni docs).
### 1.1. HTTP / Webhook / Tráfico
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|------------------------------------------|----------|-------------------|--------------------------------------------|----------------------------------------------------------------|-----------|
| `webhook_events_total_*` | counter | Webhook | `evtNorm` embebido en el nombre (`*_xxx`) | Contar eventos de webhook por tipo (messages.upsert, etc.). | core |
| `webhook_errors_total` | counter | Webhook | | Errores procesando webhooks. | core |
| `unknown_groups_discovered_total` | counter | Webhook/grupos | | Mensajes recibidos de grupos no conocidos en BD. | nice-to-have |
| `messages_blocked_group_total` | counter | Webhook/grupos | | Mensajes bloqueados por venir de grupos no permitidos. | nice-to-have |
### 1.2. Onboarding (grupos, DMs, asignaciones)
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|------------------------------------------|----------|---------------------|------------------------------------------------------------|-----------------------------------------------------------------|----------------|
| `onboarding_prompts_sent_total` | counter | Onboarding-grupos | `group_id`, `source`, `reason` | Prompts de onboarding enviados al grupo. | core (producto)|
| `onboarding_prompts_skipped_total` | counter | Onboarding-grupos | `group_id`, `source?`, `reason` | Casos donde se decide no enviar prompt al grupo. | core (producto)|
| `onboarding_assign_failures_total` | counter | Onboarding-asignac. | `group_id`, `source`, `reason` | Fallos al autoasignar tarea en onboarding. | nice-to-have |
| `onboarding_dm_skipped_total` | counter | Onboarding-DM | `reason`, `group_id` | Razones por las que NO se envía DM de onboarding. | core (producto)|
| `onboarding_dm_sent_total` | counter | Onboarding-DM | `variant`, `part`, `group_id` | DMs de onboarding efectivamente enviados. | core (producto)|
| `onboarding_recipients_capped_total` | counter | Onboarding-DM | `group_id` | Número de destinatarios que se quedaron fuera por cap. | nice-to-have |
| `onboarding_bundle_sent_total` | counter | Onboarding-DM | `variant`, `group_id` | “Bundles” de onboarding enviados. | nice-to-have |
| `onboarding_dm_sent_abs` | gauge | Onboarding-analytics| | Valor absoluto de DMs enviados (derivado). | debug |
| `onboarding_recipients_abs` | gauge | Onboarding-analytics| | Destinatarios totales (derivado). | debug |
| `onboarding_converted_users_abs` | gauge | Onboarding-analytics| | Usuarios convertidos (derivado). | debug |
| `onboarding_conversion_rate` | gauge | Onboarding-analytics| | Ratio de conversión calculado. | debug / dudosa |
### 1.3. Reacciones / Cola de respuestas
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|--------------------------------------------------|----------|------------------|-------------------------|--------------------------------------------------------|--------------|
| `reactions_enqueued_total` | counter | Reacciones/cola | `emoji` | Reacciones encoladas para enviar. | nice-to-have |
| `reactions_sent_total` | counter | Reacciones/cola | `emoji` | Reacciones enviadas con éxito. | nice-to-have |
| `reactions_failed_total` | counter | Reacciones/cola | `emoji` | Reacciones que fallaron al enviar. | nice-to-have |
| `responses_skipped_unresolvable_recipient_total` | counter | Cola respuestas | `reason` (`non_numeric`, `too_long`, `bad_domain`…) | Respuestas descartadas por no poder resolver el JID. | debug (útil) |
### 1.4. Recordatorios
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|----------------------------------------|----------|--------------|--------------------|----------------------------------------------------------|--------------|
| `reminders_skipped_outside_window_total` | counter | Recordatorios| | Recordatorios omitidos por estar fuera de ventana horaria. | dudosa (parcial) |
### 1.5. Group sync / grupos / miembros
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|--------------------------------------|----------|---------------|-----------------------------|-----------------------------------------------------------------|--------------|
| `sync_runs_total` | counter | Group sync | | Número de ejecuciones de sync. | core (ops) |
| `sync_errors_total` | counter | Group sync | | Errores en ejecuciones de sync. | core (ops) |
| `sync_skipped_group_total` | counter | Group sync | | Grupos ignorados en la reconciliación (varios motivos). | nice-to-have |
| `allowed_groups_labels_filled_total` | counter | Group sync | | Conteo de grupos donde se rellenaron labels de allowed_groups. | debug |
| `active_groups` | gauge | Group sync | | Número de grupos activos cacheados. | core |
| `active_members` | gauge | Group sync | | Conteo de miembros activos (BD). | core |
| `last_sync_timestamp_seconds` | gauge | Group sync | | Marca de tiempo del último sync correcto. | core |
| `last_sync_ok` | gauge | Group sync | | 1 si último sync OK, 0 si falló. | core |
| `last_sync_duration_ms` | gauge | Group sync | | Duración del último sync. | core |
| `alias_coverage_ratio` | gauge | Group sync | `group_id` | Cobertura de alias de identidad en el grupo. | debug/nice |
| `allowed_groups_total_pending` | gauge | Allowed groups| | Grupos en estado `pending`. | core |
| `allowed_groups_total_allowed` | gauge | Allowed groups| | Grupos en estado `allowed`. | core |
| `allowed_groups_total_blocked` | gauge | Allowed groups| | Grupos en estado `blocked`. | core |
| `group_sync_seconds_until_next` | gauge | Group sync | | Segundos hasta el próximo sync, o -1 si inactivo. | core |
### 1.6. Identidad / alias
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|-----------------------------------|----------|-----------|--------------------|----------------------------------------------------|----------|
| `identity_alias_upsert_errors_total` | counter| Identidad | | Errores al hacer upsert de alias. | debug |
| `identity_alias_upserts_total` | counter| Identidad | | Número de upserts de alias realizados. | debug |
| `identity_alias_resolved_total` | counter| Identidad | | Alias resueltos correctamente. | debug |
| `identity_alias_unresolved_total` | counter| Identidad | | Casos en los que no se pudo resolver alias. | debug |
### 1.7. Administración (allow/block/list)
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|----------------------------|----------|-------------|--------------------|--------------------------------------------------------|--------------|
| `admin_actions_total_allow`| counter | Admin | | Acciones de “allow” hechas por admins. | nice-to-have |
| `admin_actions_total_block`| counter | Admin | | Acciones de “block” hechas por admins. | nice-to-have |
| `admin_actions_total_list` | counter | Admin | | Invocaciones a listados de allowed_groups. | nice-to-have |
### 1.8. Comandos
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|----------------------------|----------|------------|------------------------|----------------------------------------------------------|---------------|
| `commands_alias_used_total`| counter | Comandos | `action=info|mias|...` | Uso de alias de comandos. | nice-to-have |
| `commands_unknown_total` | counter | Comandos | | Mensajes que no se mapean a ningún comando. | core (debug/ux)|
| `commands_blocked_total` | counter | Comandos | | Comandos bloqueados (p.ej. grupo no permitido). | core (producto/ops) |
| `ver_dm_transition_total` | counter | Comandos | | Veces que se hace transición a “ver por DM”. | nice-to-have |
| `web_tokens_issued_total` | counter | Web tokens | | Número de tokens web emitidos. | nice-to-have |
### 1.9. Mantenimiento / “evolution” (instancia WA)
| Métrica | Tipo | Ámbito | Labels principales | Uso actual / intención | Categoría |
|-------------------------------------------|----------|--------------|----------------------------|-------------------------------------------------------------|------------|
| `evolution_instance_state_changes_total` | counter | Evolution | `instance` | Número de cambios de estado de la instancia. | core (ops) |
| `evolution_health_check_errors_total` | counter | Evolution | `instance` | Errores en health checks. | core (ops) |
| `evolution_instance_restart_attempts_total`| counter | Evolution | `instance` | Intentos de reinicio de la instancia. | core (ops) |
| `evolution_instance_restart_success_total`| counter | Evolution | `instance` | Reinicios exitosos de la instancia. | core (ops) |
| `evolution_instance_state` | gauge | Evolution | `instance`, `state` | Estados actuales de la instancia (por valor de `state`). | core (ops) |
| `evolution_instance_last_state_change_ts` | gauge | Evolution | `instance` | Timestamp del último cambio de estado. | nice-to-have |
| `evolution_instance_state_age_seconds` | gauge | Evolution | `instance` | Tiempo en segundos en el estado actual. | nice-to-have |
---
## 2. Propuesta de set “core v1” (existentes)
### 2.1. Operación / salud
**Mantener como core:**
- Webhook / HTTP:
- `webhook_events_total_*`
- `webhook_errors_total`
- Group sync:
- `sync_runs_total`
- `sync_errors_total`
- `active_groups`
- `active_members`
- `last_sync_timestamp_seconds`
- `last_sync_ok`
- `last_sync_duration_ms`
- `group_sync_seconds_until_next`
- `allowed_groups_total_pending`
- `allowed_groups_total_allowed`
- `allowed_groups_total_blocked`
- Evolution / instancia WA:
- `evolution_instance_state_changes_total`
- `evolution_health_check_errors_total`
- `evolution_instance_restart_attempts_total`
- `evolution_instance_restart_success_total`
- `evolution_instance_state`
### 2.2. Experiencia de usuario / producto
**Mantener como core:**
- Onboarding:
- `onboarding_prompts_sent_total`
- `onboarding_prompts_skipped_total`
- `onboarding_dm_sent_total`
- `onboarding_dm_skipped_total`
- Comandos:
- `commands_unknown_total`
- `commands_blocked_total`
---
## 3. Métricas existentes marcadas como “nice-to-have” o “debug”
### 3.1. Nice-to-have (mantener pero sin contrato fuerte)
- Webhook / grupos:
- `unknown_groups_discovered_total`
- `messages_blocked_group_total`
- Onboarding:
- `onboarding_assign_failures_total`
- `onboarding_recipients_capped_total`
- `onboarding_bundle_sent_total`
- Reacciones:
- `reactions_enqueued_total` / `reactions_sent_total` / `reactions_failed_total`
- Group sync:
- `sync_skipped_group_total`
- `alias_coverage_ratio` (si se usa en dashboards)
- Administración:
- `admin_actions_total_allow`
- `admin_actions_total_block`
- `admin_actions_total_list`
- Comandos:
- `commands_alias_used_total`
- `ver_dm_transition_total`
- `web_tokens_issued_total`
- Evolution:
- `evolution_instance_last_state_change_ts`
- `evolution_instance_state_age_seconds`
### 3.2. Debug / dudosas (candidatas a simplificar o eliminar)
- Onboarding analytics:
- `onboarding_dm_sent_abs`
- `onboarding_recipients_abs`
- `onboarding_converted_users_abs`
- `onboarding_conversion_rate`
- Identidad / alias:
- `identity_alias_upsert_errors_total`
- `identity_alias_upserts_total`
- `identity_alias_resolved_total`
- `identity_alias_unresolved_total`
- Cola de respuestas:
- `responses_skipped_unresolvable_recipient_total` (debug útil → mantener como tal).
- Recordatorios:
- `reminders_skipped_outside_window_total` (parcial: solo una razón de skip, sin contexto de enviados totales).
---
## 4. Métricas nuevas propuestas (faltantes importantes)
> Nota: nombres sujetos a ajuste, pero la idea es que sean lo más “Prometheus-friendly” posible.
### 4.1. Tareas
- **Counters (idealmente derivables de BD, o directamente desde DB en `/metrics`):**
- `tasks_created_total`
- Definición: `COUNT(*) FROM tasks`.
- `tasks_completed_total`
- Definición: `COUNT(*) FROM tasks WHERE completed = 1`.
- **Gauges (derivables de BD):**
- `tasks_active`
- Definición: tareas no completadas (criterio exacto según modelo).
- `tasks_overdue`
- Definición: tareas no completadas con `due_date < hoy`.
- (Opcional) `tasks_active_by_group` con label `group_id` **solo si** el número de grupos es manejable y se considera útil.
### 4.2. Mensajes y cola de respuestas
- **Tráfico recibido (webhook):**
- `bot_messages_received_total` (counter, en memoria)
- Labels: `kind=text|reaction|system|other`.
- **Tráfico enviado por el bot (muy importante, idealmente persistente):**
- `bot_messages_sent_total` (counter, **persistente** o derivado de BD si posible)
- Labels: `kind=reply|reminder|onboarding|error|other`.
- **Cola de respuestas:**
- Counters:
- `response_queue_enqueued_total` (por tipo de mensaje/reacción).
- `response_queue_sent_total`.
- `response_queue_failed_total`.
- `response_queue_retried_total`.
- `response_queue_exhausted_total` (cuando se dan por fallidos tras reintentos).
- Gauges (desde BD):
- `response_queue_pending`
- `COUNT(*) FROM response_queue WHERE status='pending'`.
- `response_queue_oldest_age_seconds`
- `now - MIN(created_at)` de los pendientes.
### 4.3. Recordatorios (visión completa)
- Counters:
- `reminders_scheduled_total`
- Cuando se programa un recordatorio.
- `reminders_sent_total`
- Recordatorios enviados efectivamente.
- `reminders_failed_total`
- Intentos de envío de recordatorio fallidos.
- `reminders_skipped_total`
- Con labels `reason=outside_window|user_opt_out|group_not_allowed|gating|invalid_time|other`.
- Opcionalmente ratios calculables en dashboards:
- `reminders_skipped_total / (reminders_sent_total + reminders_skipped_total)`.
### 4.4. Uso de ICS / Web
- ICS:
- `ics_requests_total` (counter)
- Labels: `type=personal|group|aggregate`, `status_class=2xx|4xx|5xx`.
- HTTP genérico (si se desea):
- `http_requests_total`
- Labels: `handler=webhook|metrics|ics|web_ui|...`, `status_class=2xx|4xx|5xx`.
### 4.5. Otras métricas posibles (según prioridad)
- Usuarios / grupos (como gauges desde BD):
- `groups_total`, `groups_active_total`.
- `group_members_total` (activos).
- `users_total`.
- `users_active_30d` (si hay `last_seen_at`).
---
## 5. Persistencia vs. métricas derivadas
### 5.1. Derivadas desde BD (sin cambiar `Metrics`)
Buenas candidatas:
- `tasks_*` (`created`, `completed`, `active`, `overdue`).
- `groups_*` (`total`, `active`).
- `group_members_total`.
- `allowed_groups_total_*` (ya se hace).
- `response_queue_pending`, `response_queue_oldest_age_seconds`.
Ventaja: son **persistentes por diseño**, no dependen de reinicios del proceso.
### 5.2. Contadores en memoria (se reinician)
Buenas candidatas:
- Tráfico “reciente”:
- `bot_messages_received_total`.
- `http_requests_total`.
- Eventos de corto plazo:
- `sync_runs_total`, `sync_errors_total`.
- `evolution_*` (si además se pueden inferir de logs/BD, no es grave que se reinicien).
Estos están bien para **tendencias recientes**, SLIs y alertas basadas en tasas.
### 5.3. Contadores que probablemente queremos **persistir**
Lista corta para no complicar demasiado:
- `bot_messages_sent_total`
- `reminders_sent_total`
- (Opcional) `webhook_events_received_total` (si se agrega unificado, en lugar de solo por tipo).
Opciones:
1. Crear una tabla `persistent_metrics(name TEXT PRIMARY KEY, value INTEGER NOT NULL)`.
2. Implementar funciones de “incremento persistente” que actualicen BD y, opcionalmente, el estado de `Metrics`.
3. Al renderizar `/metrics`, leer estos valores persistentes y exponerlos.
---
## 6. Próximos pasos sugeridos
1. **Validar este set “core v1”**:
- Confirmar que las métricas “core existentes” listadas arriba son realmente las que quieres cuidar.
- Elegir cuáles de las nuevas propuestas son **imprescindibles** en la primera iteración (p.ej. tareas + mensajes + cola + recordatorios).
2. **Definir contrato de nombres**:
- Cerrar nombres finales de:
- `tasks_*`
- `bot_messages_*`
- `response_queue_*`
- `reminders_*`
- `ics_requests_total` / `http_requests_total`.
3. **Implementar por fases**:
- Fase 1: gauges derivadas de BD en `/metrics` (tareas, cola, grupos, etc.).
- Fase 2: counters en memoria (mensajes recibidos/enviados, recordatorios, cola).
- Fase 3: mecanismo de métricas persistentes y migrar los 23 contadores elegidos.
4. **Limpiar / reclasificar métricas “debug/dudosas”**:
- Mantener `responses_skipped_unresolvable_recipient_total` como debug útil.
- Simplificar o eliminar gauges de onboarding `*_abs` / `conversion_rate` si no se usan.
- Revisar `reminders_skipped_outside_window_total` cuando exista el set completo de `reminders_*`.
Este documento sirve como referencia para saber qué métricas existen, cuáles son “de contrato” y cuáles se pueden tocar con menos miedo, además de qué huecos importantes hay que cubrir en próximas iteraciones.
Loading…
Cancel
Save