# 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 2–3 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.