Ir al contenido

Métricas y dashboards

Thulu mide dos cosas distintas. Del trabajo que hacen los agentes saca las métricas de flujo de cada proyecto (cuánto tarda una tarea, cuántas vuelven, cuánto cuestan) sin que configures nada. De tu aplicación en producción recibe lo que le mande por OpenTelemetry (OTLP) en cada entorno del proyecto: con eso arma las señales fijas del entorno (latencia, errores, requests) y te deja graficar tus propias métricas en dashboards. Quien opera la instalación tiene además un endpoint Prometheus con las métricas del servidor.

  1. Abrí “Proyectos” y entrá a un proyecto. La pestaña “Resumen” es la primera.

  2. Elegí el rango con “Desde” y “Hasta” o con los presets. Las métricas cuentan sólo las tareas vinculadas a ese proyecto.

    Resumen del proyecto tienda-web con doce tarjetas de métricas y los gráficos Flujo y Gasto
    tienda-web en 30 días: 11 tareas terminadas, lead time mediano de 44 h y 3 de 14 tareas devueltas al menos una vez.
  3. Bajá a “Dónde se va el tiempo” para ver en qué etapa se quedan quietas las tareas, y a “Censo del tablero” para ver cuántas hay en cada etapa ahora.

    Barras de permanencia mediana por etapa: Revisión 24 h, Backlog 17 h, En curso 26 minutos; y el censo de tareas por etapa
    Mediana de 24 h en Revisión contra 26 minutos en En curso: las tareas esperan la revisión más que al agente.
Tarjeta Qué cuenta
“Abiertas” Tareas vinculadas que hoy no están en una etapa terminal, incluidas las que esperan en la primera columna. Es una foto de ahora: no depende del rango.
“Rendimiento” Tareas terminadas dentro del rango.
“Lead time · p50” Tiempo mediano entre que se creó una tarea y se terminó, con el p90 debajo.
“Éxito al primer intento” Terminadas que nunca volvieron atrás. Una sola devolución en toda su historia la descalifica, aunque haya sido antes del rango.
“Tasa de retrabajo” Tareas que fueron devueltas a una etapa anterior, con la cantidad de devoluciones.
“Corridas / tarea” Cuántas veces corrió un agente por tarea, en promedio.
“Intervenciones humanas / tarea” Comentarios escritos por personas, por tarea. Los de agentes y del sistema no cuentan.
“Caché del modelo” Parte de la entrada del modelo que salió de su caché de prompts.
“Costo / tarea” y “Costo / terminada” Gasto de agentes dividido por las tareas con actividad en el rango o por las terminadas en el rango.
“Tiempo de agente / tarea” Mediana del tiempo que los agentes estuvieron corriendo por tarea, con el tiempo real debajo.
“Tokens / tarea” Tokens de agentes por tarea, caché incluida, con el total debajo.

“Dónde se va el tiempo” sólo usa estadías cerradas: si una tarea entró a Revisión y sigue ahí, no suma hasta que salga. Más abajo están “Costo por etapa”, “Costo por modelo” y “Tareas más caras” del proyecto; el gasto del workspace entero está en Uso y costos.

Para que un entorno reciba datos de tu aplicación necesitás un token de ingesta de ese entorno y un SDK o un collector de OpenTelemetry apuntado a Thulu. El entorno se crea antes en la pestaña “Entornos” del proyecto, como se cuenta en Proyectos. Crear y revocar tokens, aprobar métricas y armar o aprobar dashboards es de admins del workspace; mirar los datos, de cualquiera que vea el proyecto.

  1. Si tu instalación se publica con otra dirección que la que usás para entrar (un proxy, un dominio), cargala en Configuración, “API”, panel “Dirección de telemetría”, y tocá “Guardar”. Vale para toda la instalación, así que sólo la puede guardar quien la opera; los demás la ven bloqueada. Es la dirección que arma el bloque de variables del modal “Telemetría” y la que se les pasa a los agentes cuando tienen que explicarle a alguien cómo conectar una app.

    Panel Dirección de telemetría con un campo vacío, una dirección de ejemplo y el botón Guardar
    Sin dirección, el modal usa la del navegador y a los agentes se les dice que es desconocida.
  2. En el proyecto, abrí “Entornos” y tocá el ícono del rayo (“Telemetría”) del entorno.

  3. Escribí el “Nombre del token” (por ejemplo collector-prod; con eso distinguís los collectors en la tabla) y tocá “Nuevo token”. El modal muestra el token y un bloque con tres variables. Copialo en ese momento: el token no se vuelve a mostrar.

    Modal Telemetría de production con un token nuevo, el aviso Copialo ahora, las variables OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS y OTEL_SERVICE_NAME, y el aviso de que falta la Dirección de telemetría
    El token sólo puede escribir telemetría en este entorno.
  4. Si querés que sólo ciertas redes puedan mandar datos, tocá el ícono de engranaje (“Direcciones permitidas”) en la fila del token. En “IPs o rangos CIDR” escribí las direcciones separadas por comas (por ejemplo 10.0.0.0/8, 203.0.113.7). Vacío significa “cualquier dirección”.

  5. Configurá las tres variables en tu app o en tu collector y reemplazá <your service> por el nombre del servicio. Revisá que OTEL_EXPORTER_OTLP_ENDPOINT apunte a la dirección pública de Thulu seguida de /ingest.

  6. Volvé al modal: “De dónde llegan los datos” muestra cada dirección que presentó el token, con aceptados, rechazados y la última vez que se la vio.

Thulu acepta OTLP por HTTP, en JSON o protobuf, en /ingest/v1/metrics, /ingest/v1/traces y /ingest/v1/logs, con el token en el header x-octopus-token (o como Authorization: Bearer). Los logs se aceptan y se descartan: hoy no se guardan. Cada envío puede pesar hasta 4 MiB, y cada token tiene un tope de 600 envíos por minuto; pasado eso la app recibe un 429 con Retry-After.

Cuando un envío se rechaza, la app recibe siempre la misma respuesta, para no darle pistas a quien prueba tokens. El motivo (“token revocado”, “token no reconocido”, “dirección fuera de la lista permitida”) se ve sólo en “De dónde llegan los datos”. El ícono de tacho (“Revocar”) pide confirmación, corta el token en el acto y no se puede deshacer.

De las trazas toma los spans de servidor y de consumidor (los que genera cualquier autoinstrumentación) y calcula, por servicio y cada 5 minutos, “Latencia p50”, “Latencia p95”, “Errores” y “Requests”. Un span cuenta como error si su estado es error o si la respuesta HTTP fue 5xx. De las métricas toma system.cpu.utilization, process.cpu.utilization, container.cpu.utilization y sus equivalentes de memoria para “CPU” y “Memoria”. Esas son las señales fijas del entorno. Aparecen como tarjetas debajo de la fila del entorno, con la marca “reportado por la app”, alrededor de un minuto después de que cierra cada intervalo de 5 minutos.

Fila del entorno prod con seis tarjetas de checkout: CPU 33,6 %, Errores 0,0 %, Latencia p50 142ms, Latencia p95 216ms, Memoria 51,3 % y Requests 0.02/s, cada una con su línea y la marca reportado por la app
Las señales fijas que salen de las trazas y de las métricas de CPU y memoria de la app, sin configurar nada en Thulu.

Cualquier otra métrica que mande la app pasa a “Métricas custom”.

Cada métrica nueva aparece en el entorno como “descubierta”: Thulu guarda el nombre, el servicio, el tipo y los labels, pero no la deja graficar hasta que alguien la apruebe. Así una app que manda cientos de métricas no llena los dashboards sola.

Bloque Métricas custom con 5 en espera: checkout_errors y orders_completed como contador con un label, debug_retry_tmp, redis_hit_ratio y queue_depth sin labels, cada una con Aprobar y Rechazar
Cinco métricas recién llegadas. El nombre va precedido del servicio que la mandó.
  • “Aprobar” la habilita para dashboards y para que los agentes la lean.
  • “Rechazar” deja la fila en gris y deja de guardar sus puntos. La fila se conserva para que la métrica no vuelva a aparecer como nueva en el próximo envío.

Las dos acciones se aplican con un clic. Las métricas resueltas quedan en la lista con la marca “aprobada” o “rechazada”, y cada una tiene “Volver a espera” y un botón para eliminarla. Eliminar pide confirmación y borra también los puntos guardados; si la app la sigue mandando, vuelve como en espera.

Lo que manda la app Cómo lo guarda Thulu
Suma monotónica (un contador OTLP) “contador”. Se guarda cuánto subió en cada intervalo; si el contador vuelve a cero porque la app reinició, el valor nuevo cuenta como incremento. El primer valor que llega sólo sirve de punto de partida.
Gauge o suma no monotónica “medidor”. Se guarda el valor tal cual.
Histograma Se ignora.

Los puntos se agrupan cada 5 minutos y se guardan 90 días. Hay techos por entorno: 50 métricas, 6 labels por métrica (si hay más, se quedan los 6 primeros en orden alfabético) y 20 valores distintos por label; a partir del valor 21 todo se junta en other. Cuando el entorno llega al 80% de su cupo de métricas aparece un contador “registradas” junto al título.

Debajo de las métricas custom está el bloque “Dashboards” del entorno: una pestaña por dashboard, “+ nuevo” y “Editar”. Mientras no haya ninguna métrica aprobada, el bloque dice “Aprobá una métrica custom de arriba para armar un dashboard.”

Entorno prod con cuatro métricas resueltas, una en espera, y el dashboard Salud del checkout con barras por medio de pago, un número de 144 con su variación y una línea de pedidos por canal
Un dashboard con tres paneles: barras, número único y línea. Cada panel dice el rango que muestra.
  1. Tocá “+ nuevo” y escribí el “Nombre”.

  2. Completá el primer panel, que arranca como “Línea” con la primera métrica aprobada. Arriba van “Título” y “Gráfico”. Debajo, “Métrica”, “Agregación”, “Dividir por” (el label), “Horas” (hasta 2160, los 90 días que se guardan) y “Ancho” (“media fila” o “fila completa”). “Gráfico” ofrece sólo los tipos que le sirven a la métrica elegida.

    Modal Nuevo dashboard con el nombre Salud del checkout y tres paneles: barras de errores por medio de pago, número único con el pico de la cola y línea de pedidos por canal
    Siete campos por panel. Elegí primero la métrica: de ella dependen las agregaciones y los labels que se ofrecen.
  3. “Agregar panel” suma otro. Hasta 12 por dashboard.

  4. Tocá “Guardar”. Un dashboard que creás vos se publica directo, sin pasar por aprobación.

Tipo Series Label para dividir Sirve para
“Línea” 1 a 4 Opcional Evolución en el tiempo, una línea por valor del label
“Área apilada” 1 Obligatorio Cómo se reparte un total en el tiempo. Sólo contadores
“Barras” 1 Obligatorio Comparar los valores de un label en el rango
“Número único” 1 No admite (el selector se desactiva) Un número con una línea chica y la variación contra el período anterior
“Tabla” 1 a 6 Obligatorio Varios números por valor del label

Para un contador podés agregar con sum, avg, max o min; para un medidor, con avg, max, min o last. Al cambiar a Barras, Área apilada o Tabla el editor elige solo el primer label de la métrica. Una métrica sin labels no ofrece esos tres tipos, y un medidor no ofrece Área apilada.

“Editar” abre el dashboard de la pestaña elegida con el mismo formulario; guardar no lo manda de nuevo a aprobación. Un panel con más de una serie se ve como “N series: editalas desde la API” y desde la UI no podés cambiarle las métricas ni la agregación; el resto de los campos sí. Para sacar un panel, usá el tacho de su fila (“Quitar panel”). Un dashboard publicado se puede eliminar: deja de verse para todos y las métricas y su historial quedan.

Un agente con el MCP octopus-api con permiso de escritura en su etapa puede listar las métricas del entorno, leer sus puntos y proponer un dashboard. La skill del sistema octopus-observability le explica cómo hacerlo. Lo que propone queda inerte: se ve en una pestaña marcada “propuesto”, pero no se publica hasta que un admin lo apruebe. Si el agente lo propuso desde una tarea, además se suma una aprobación pendiente a esa tarea, que aparece en Pendientes en el idioma de quien la lee.

  1. Abrí la pestaña marcada “propuesto”. Arriba de los paneles se ve quién lo propuso y cuántos paneles tiene.

    Banner de dashboard propuesto por agent:observabilidad con dos paneles, botones Aprobar y Descartar, y los paneles de área apilada y tabla debajo
    Los paneles ya muestran datos reales, así que podés ver el resultado antes de aprobarlo.
  2. Tocá “Aprobar” y confirmá. Si ya había un dashboard publicado con el mismo nombre, queda archivado. “Descartar” pide confirmación y borra los paneles propuestos; las métricas y sus datos quedan.

    Diálogo ¿Publicar Medios de pago? con el texto sobre archivar la versión activa del mismo nombre y los botones Cancelar y Aprobar
    Aprobar el dashboard también aprueba la revisión pendiente de la tarea.

Los agentes no tienen forma de aprobar sus propios dashboards. Cómo darle a un agente el MCP con escritura está en MCPs y las skills del sistema en Skills.

Las señales fijas de un entorno también pueden salir de la cuenta de nube en lugar de la app. Para eso el entorno necesita proveedor AWS o Google Cloud y una credencial vinculada (“+ vincular credencial”); un agente propone de dónde sale cada señal (latencia, errores, CPU, reinicios, costo diario) y la propuesta aparece en el entorno como “N mapeos propuestos” con “Aprobar”. Nada se recolecta hasta que la aprobás. Después Thulu recolecta solo, y el ícono de flechas (“Recolectar ahora”) fuerza una lectura.

Entorno prod de tienda-api con proveedor aws, región us-east-1, credencial cargada y la marca sin mapear; debajo, el banner 7 mapeos propuestos por agent:observabilidad con cuenta·cost_daily, tienda-api·cpu, tienda-api·memory, tienda-api·restarts, tienda-api-alb·error_rate, tienda-api-alb·latency_p95 y tienda-api-alb·throughput, y el botón Aprobar
El agente propuso de dónde sale cada señal: latencia, errores y tráfico del balanceador, CPU, memoria y reinicios del servicio de ECS, y el costo de la cuenta. Hasta aprobar, el entorno sigue sin mapear.

Con proveedor Prometheus u “Otro”, Thulu no recolecta nada desde afuera: las señales sólo se llenan con lo que la app manda por OTLP.

El servidor publica sus propias métricas en GET /metrics, en el formato de Prometheus. Entre ellas: requests HTTP y su duración, sandboxes activos, tareas por tablero y etapa (octopus_tasks_by_stage), corridas de agentes por tipo y motivo de corte (octopus_agent_runs_total), tokens por modelo (octopus_tokens_consumed_total), costo por modelo (octopus_cost_usd_total), eventos de autenticación y lecturas de métricas de entornos, además de las métricas estándar del proceso Go.

Para leerlas hay dos caminos:

  • Definí OCTOPUS_METRICS_TOKEN en el daemon y configurá el scraper con Authorization: Bearer <token>.
  • Sin esa variable, /metrics responde sólo a un admin del workspace operador (OCTOPUS_OPERATOR_WORKSPACE), o a cualquiera en modo desarrollo.

Estas métricas cubren toda la instalación, no un workspace. Los chequeos de salud están en /health, /health/live y /health/ready. El resto de la operación está en Operación self-hosted y los recursos de la máquina en Infraestructura.

Qué ves Por qué Qué hacer
El bloque Dashboards pide aprobar una métrica No hay ninguna métrica aprobada Aprobá al menos una en “Métricas custom”
La app manda datos pero no aparece nada El endpoint apunta a otra dirección, o el envío se rechaza Mirá “De dónde llegan los datos”: si la dirección figura con rechazados, revisá el token y la lista de permitidos; si no figura, revisá OTEL_EXPORTER_OTLP_ENDPOINT
Una métrica que mandás no aparece Es un histograma, o el entorno ya tiene 50 métricas Mandala como contador o gauge, o borrá métricas que no uses
Un panel de contador queda vacío al principio El primer valor de un contador sólo sirve de base Esperá al siguiente envío
“Gráfico” no ofrece Área apilada, Barras o Tabla La métrica no tiene labels, o es un medidor (Área apilada pide un contador) Elegí otra métrica o quedate con “Línea” o “Número único”
Un label muestra other Pasó los 20 valores distintos Cambiá el label por uno con menos valores
Un entorno Prometheus u “Otro” no muestra señales Thulu no recolecta de esos proveedores (el formulario del entorno lo avisa) Mandá trazas por OTLP desde la app