Métricas y logs
Recolección de métricas, logs y traces sin montar una pila de observabilidad externa. Cuándo vale, y cuándo integrar con herramienta de fuera.
La observabilidad suele exigir una pila de software paralela al cluster: agente de métrica en cada nodo, serie temporal central, agregador de logs, dashboard, alertador, tracer. Cinco componentes, cada uno con su configuración, su actualización, su factura.
HeroCtl resuelve eso por dentro. Métricas, logs, alertas y tracing ya vienen embebidos en el plano de control. Solo enchufas herramienta externa cuando el equipo tiene motivo concreto para eso.
Métricas
El endpoint estándar
Cada nodo servidor expone métricas en formato Prometheus en /v1/metrics:
curl -H "X-Heroctl-Token: $TOKEN" https://manage.exemplo.com/v1/metrics
Salida típica (recortada):
# HELP heroctl_node_cpu_usage_percent CPU em uso por nó
# TYPE heroctl_node_cpu_usage_percent gauge
heroctl_node_cpu_usage_percent{node="server-1"} 23.4
heroctl_node_cpu_usage_percent{node="server-2"} 18.1
# HELP heroctl_alloc_memory_bytes Memória usada por alocação
# TYPE heroctl_alloc_memory_bytes gauge
heroctl_alloc_memory_bytes{job="api",alloc="abc123"} 285212672
Lo que viene listo
| Familia de métricas | Ejemplos |
|---|---|
| Nodos | CPU, RAM, disco, red, load average, uptime |
| Asignaciones | CPU, RAM, restarts, status, edad |
| Jobs | Réplicas saludables, asignaciones pendientes, deploys activos |
| Router | Requests/s, latencia p50/p95/p99, errores 5xx por host |
| Ingress TLS | Validez de certificado, fallos de renovación |
| API interna | Latencia, throughput, tasa de error |
En un cluster recién instalado, eso ya alimenta un panel completo sin ninguna configuración extra.
Métricas customizadas de la aplicación
Tu aplicación expone /metrics en cualquier puerto, en formato Prometheus. Decláralo en el spec:
job: api-pagamentos
metrics:
enabled: true
path: /metrics
port: 9090
interval: 15s
El cluster hace el scrape, agrega y disponibiliza en el mismo endpoint /v1/metrics. Las métricas salen etiquetadas con job, alloc, node, así que la búsqueda es directa:
rate(http_requests_total{job="api-pagamentos",status=~"5.."}[5m])
Cliente Prometheus existe oficialmente para Go, Python, Java, Node.js, Ruby, .NET, Rust y PHP. En cualquiera de esos lenguajes, instrumentar una aplicación toma quince minutos.
Panel embebido
El panel admin (puerto 8443) trae una sección de gráficos lista:
- Vista de cluster: CPU, RAM, red agregadas
- Vista de job: réplicas, restarts, latencia del router
- Vista de asignación: stream de logs, métricas individuales
- Vista de host: detalle de cada nodo, asignaciones en él
Para la mayoría de los equipos, ese panel sustituye un Grafana montado por fuera. Cuando necesitas dashboards muy customizados o correlación con fuentes externas, vale conectar un Grafana al endpoint /v1/metrics como datasource Prometheus común.
Logs
Modelo de recolección
Cada asignación tiene stdout y stderr capturados por el agente local, comprimidos y enviados al escritor central de logs del cluster. No hay agente de logs separado para instalar, configurar o actualizar.
Tail en tiempo real
# stream do job inteiro (todas as alocações)
heroctl logs -f --job api-pagamentos
# uma alocação específica
heroctl logs -f --alloc abc123
# só stderr
heroctl logs -f --job api-pagamentos --stream stderr
Filtrado
# entre dois timestamps
heroctl logs --job api-pagamentos \
--since "2026-04-25 10:00" \
--until "2026-04-25 11:00"
# busca textual
heroctl logs --job api-pagamentos --since 1h | grep "panic"
# saída estruturada para processar com jq
heroctl logs --job api-pagamentos --since 1h --format json
Retención
Default: 30 días por asignación activa, 7 días después de que la asignación termina. Configurable en el spec del cluster:
logs:
retention:
active_days: 30
terminated_days: 7
storage:
type: local
path: /var/lib/heroctl/logs
max_size_gb: 100
Para retención más larga, exporta a storage externo (siguiente sección).
Export hacia fuera
Cuando necesitas retención de años, o correlación con logs de sistemas que no corren en el cluster, hay salidas listas:
logs:
export:
- type: syslog
destination: logs.empresa.com.br:514
protocol: tcp
tls: true
- type: loki
url: https://loki.empresa.com.br
tenant: heroctl-prod
- type: cloudwatch
region: us-east-1
log_group: /heroctl/prod
credentials: ${secret.aws_logs}
- type: elasticsearch
url: https://elastic.empresa.com.br
index: heroctl-%Y.%m.%d
credentials: ${secret.es_creds}
Varios destinos pueden correr al mismo tiempo. El cluster mantiene la copia local por el período de retención y replica a los destinos configurados.
Alertas
Una alerta es una expresión sobre métricas que dispara un webhook cuando es verdadera por tiempo configurado:
alerts:
- name: api-erro-alto
expr: |
rate(http_requests_total{job="api-pagamentos",status=~"5.."}[5m])
/ rate(http_requests_total{job="api-pagamentos"}[5m]) > 0.05
for: 5m
severity: critical
annotations:
summary: "Taxa de erro acima de 5% em api-pagamentos"
runbook: https://wiki.empresa.com.br/runbook/api-pagamentos
notify:
- type: slack
webhook: ${secret.slack_oncall}
- type: pagerduty
routing_key: ${secret.pagerduty_critical}
- name: certificado-expirando
expr: heroctl_ingress_cert_expiry_days < 14
for: 1h
severity: warning
notify:
- type: discord
webhook: ${secret.discord_ops}
Canales soportados de fábrica: Slack, Discord, PagerDuty, Opsgenie, webhook genérico. Para quien quiere integración custom (Telegram, e-mail, SMS), el webhook genérico cubre todo.
Atención: Empieza con pocas alertas críticas. Veinte alertas ruidosas se vuelven cero alertas — el equipo aprende a ignorar. Cinco alertas que siempre indican problema real son útiles.
Tracing distribuido
Tracing está disponible como opt-in en el spec del job:
job: api-pagamentos
tracing:
enabled: true
protocol: otlp
sample_rate: 0.1 # 10% das requisições
La aplicación instrumentada con OpenTelemetry envía al colector embebido. El panel muestra traces correlacionados con logs y métricas de la misma asignación.
Para visualización avanzada (timeline de spans, comparación entre traces, análisis de cola), exporta a Jaeger, Tempo o un SaaS como Honeycomb:
tracing:
export:
- type: otlp
endpoint: tempo.empresa.com.br:4317
tls: true
Comparación de costo
Para un cluster típico — 4 nodos, 30 jobs, 100 millones de requests/mes — un stack de observabilidad SaaS comercial queda entre R$ 1.000 y R$ 2.000 por mes. Un stack auto-hospedado equivalente (Prometheus + Loki + Grafana + Alertmanager + Tempo) tiene costo directo bajo, pero exige medio día de operación por semana.
| Item | Stack interno | SaaS comercial | Stack auto-hospedado |
|---|---|---|---|
| Costo directo/mes | R$ 0 | R$ 1.000–2.000 | R$ 100–300 (infra) |
| Tiempo de setup | 0 (ya corre) | 1 día | 1 a 2 semanas |
| Mantenimiento | Junto con el cluster | Cero | Algunas horas/semana |
| Límites | Para equipos hasta ~50 jobs | Prácticamente ilimitado | Lo que tu infra aguante |
| Customización de dashboard | Panel embebido | Alta | Total |
Recomendación práctica: empieza por el stack interno. Cuando la operación crezca más allá de lo que él atiende — generalmente más de 50 jobs o retención de log superior a 6 meses — exporta a Loki y Grafana auto-hospedados. SaaS comercial solo vale cuando el tiempo del equipo es más caro que la factura.
Próximos pasos
- Configurar alertas conectadas a Slack o PagerDuty antes del primer deploy crítico.
- Revisar RBAC para limitar quién ve qué logs (los logs pueden contener dato sensible).