Prompt y contexto
El histograma de latencia para una API multi-tenant muestra una regresión en p99 durante el tráfico pico. Agregar user_id, la URL completa o los parámetros de solicitud como etiquetas de métrica crearía series temporales y costos ilimitados. Mirar únicamente los buckets agregados no permite identificar una solicitud lenta individual. Diseña exemplars de métricas que adjunten una pequeña cantidad de referencias de traza a las muestras de métricas para que un investigador pueda pasar de un gráfico a una traza, y luego a los logs y dependencias.
La pregunta evalúa si separas la semántica de agregación de métricas de una referencia externa de exemplar. OpenTelemetry define un exemplar como un valor registrado asociado con un evento de métrica; puede contener trace_id, span_id, la hora de observación y atributos filtrados. Del mismo modo, OpenMetrics requiere un valor, un conjunto de etiquetas y una marca de tiempo. La métrica principal debe mantenerse con baja cardinalidad; un exemplar no es un sistema de etiquetas oculto.
Lo que evalúa el entrevistador
- Sabes que los exemplars no modifican los buckets del histograma, el count ni la suma; hacen referencia a una observación fuera del agregado.
- Puedes elegir entre muestreo basado en trazas o probabilístico y explicar la compensación entre tasa, cobertura de latencia de cola (tail latency) y costo.
- Usas referencias estables como
trace_idyspan_id, sin incluir solicitudes completas, tokens ni datos personales en las métricas. - Manejas marcas de tiempo, reordenamiento, descartes en el backend, retención y autorización multi-tenant en lugar de limitarte a trazar un enlace.
- Utilizas métricas de baja cardinalidad para encontrar una ventana de tiempo y luego usas exemplars para validar una traza representativa y seguir logs, dependencias y versiones de compilación.
Preguntas para aclarar primero
- ¿Qué backend de métricas, backend de trazas y herramienta de visualización se utilizan, y admiten consultas de exemplars y enlaces profundos (deep links)?
- ¿Qué instrumentos están dentro del alcance: Histogram, Counter o Gauge? ¿Se mide p99 en el servicio o en el gateway?
- ¿El muestreo debe apuntar a cada error, a la latencia de cola o a un presupuesto por tenant y versión? ¿Existe una política unificada entre regiones?
- ¿Qué reglas de retención, control de acceso, redacción y aislamiento de tenants restringen las referencias?
- ¿Qué presupuestos de memoria, red y almacenamiento aplican, y debe la métrica principal seguir disponible cuando se descartan los exemplars?
Una respuesta de 30 segundos
“Mantengo un histograma de latencia de baja cardinalidad y adjunto trace_id, span_id, el valor observado y la marca de tiempo solo para un conjunto pequeño muestreado. El muestreo prioriza errores y latencia de cola; los identificadores de usuario quedan fuera de las etiquetas de métrica. El backend de métricas almacena una referencia de corta duración y se realiza una verificación de permisos antes del deep link a la traza. Verifico que las estadísticas de los buckets no cambien, que la ventana de tiempo devuelva exemplars y que los descartes no afecten la métrica principal. Establezco compuertas basadas en tasa de aciertos, éxito del enlace, sobrecarga de memoria y escaneos de campos sensibles.”
Solución paso a paso
Paso 1: Establecer el límite entre métrica y exemplar
Mantén las etiquetas del histograma limitadas a dimensiones acotadas como service, route_template, region y status_class. La observación sigue contribuyendo a bucket_counts, count y sum; el exemplar almacena una referencia trazable y no debe crear una nueva serie temporal por cada traza.
Paso 2: Muestrear para cobertura de latencia de cola
Decide el muestreo de trazas en el contexto de la solicitud, luego adjunta una observación a la muestra relevante de Histogram cuando esté muestreada y coincida con un error, un umbral de latencia o un presupuesto por dimensión. Usa una capacidad fija por servicio y métrica, como un reservoir o un búfer circular (ring buffer). Controla las versiones de los cambios de muestreo para que los conteos de aciertos no se confundan con el volumen de tráfico.
Paso 3: Codificar referencias y tiempo
Un exemplar contiene un valor numérico, un conjunto de etiquetas y una hora de observación; las referencias de traza deben usar trace_id y span_id. La marca de tiempo debe ser cercana a la hora de observación y alinearse con la ventana de muestra de la métrica. Los receptores pueden truncar etiquetas o descartar exemplars, por lo que la ruta de consulta debe admitir el caso de “métrica presente, exemplar ausente”.
latency_seconds_bucket{route="/checkout",le="1"} 982
# {trace_id="4f8...",span_id="91a...",build="2026.07.31"} 1.42 1753938000000Paso 4: Limitar la privacidad, la cardinalidad y el costo
Nunca coloques URLs sin procesar, cuerpos de solicitud, direcciones de correo electrónico, tokens de autorización o IDs de usuario en un exemplar. Los atributos opcionales como build y la región necesitan una lista de permitidos (allowlist) y límites de longitud. OpenTelemetry señala que los atributos eliminados de un flujo de métricas mediante una View aún pueden exportarse como atributos filtrados del exemplar, por lo que la redacción debe configurarse por separado. Estima las muestras por segundo, los bytes por registro, la memoria del ring buffer, las escrituras remotas y el costo de consulta de trazas; reduce el muestreo de exemplars antes de contaminar las etiquetas de métricas.
Paso 5: Implementar un salto entre backends
El panel de control consulta exemplars para un rango de tiempo seleccionado y luego construye un enlace controlado hacia el backend de trazas a partir de trace_id. El servicio de enlaces verifica el tenant, la región y la autorización, y devuelve un estado explícito para trazas faltantes, expiradas o entre entornos. Los logs y los spans comparten el Trace Context, pero las tres señales no necesitan un único sistema de almacenamiento.
Paso 6: Probar la degradación y compuertas de lanzamiento
Reproduce tráfico fijo y compara buckets, count, sum y p99 antes y después de habilitar exemplars para demostrar que la agregación no ha cambiado. Inyecta solicitudes lentas y con errores para verificar la tasa de aciertos, las marcas de tiempo, los saltos a trazas y el aislamiento de tenants. Retrasa, trunca o deshabilita el backend de exemplars y confirma que las consultas de métricas sigan funcionando. Las compuertas deben cubrir escaneos de campos sensibles, límites de memoria, tasa de fallos de escritura remota, éxito de saltos y equidad de muestreo por servicio y versión.
Una respuesta de ejemplo sólida
“Primero limito las etiquetas de las métricas a plantillas de rutas, clases de estado y región, dejando que el histograma se encargue de la agregación de p99. Las solicitudes llevan Trace Context; cuando una traza muestreada coincide con una política de error o latencia de cola, adjunto trace_id, span_id, el valor y la marca de tiempo a la muestra de Histogram. Los atributos del exemplar están en una lista de permitidos, no contienen identidad de usuario ni cuerpos de solicitud, y se redactan nuevamente antes de la exportación mediante View.”
“Las consultas de Prometheus/OpenMetrics devuelven exemplars solo para la ventana seleccionada. Se realiza una verificación de permisos antes del enlace a la traza; si la traza ha expirado, la métrica permanece visible con un estado de referencia expirada. Las pruebas de carga comparan bucket/count/sum/p99, y los simulacros cubren descartes en el backend, reordenamientos, acceso entre tenants y presupuestos agotados. La tasa de aciertos, el tiempo hasta la primera traza, la memoria, el costo de escritura y los escaneos de campos sensibles determinan el presupuesto de muestreo; las etiquetas de alta cardinalidad nunca entran en la métrica.”
Errores comunes
- Poner
trace_iden las etiquetas de métricas → explosión de series temporales → mantenerlo en la referencia del exemplar. - Usar solo muestreo de probabilidad fija → p99 o los errores pueden estar ausentes durante largos periodos → agregar muestreo de cola, de errores y presupuestado.
- Ignorar las marcas de tiempo del exemplar → la traza queda fuera de la ventana del gráfico → registrar la hora de observación y validar la ventana.
- Asumir que los atributos filtrados son seguros → los datos sensibles aún pueden exportarse con los exemplars → usar una lista de permitidos independiente, redacción y verificación de autorización.
- Tratar los exemplars faltantes como un fallo de la métrica → la agregación queda acoplada a las referencias → mantener las métricas disponibles y monitorear la pérdida de exemplars por separado.
- Retener referencias sin límites → la memoria y el costo crecen sin control → usar capacidad fija, retención y presupuestos de muestreo.
Preguntas de seguimiento y respuestas
¿Un exemplar modifica p99?
No. Su valor ya está incluido en el bucket, count y sum de Histogram. Agrega contexto y una referencia; no debe crear otra serie métrica ni contar la observación dos veces.
¿Por qué no poner la URL completa en un atributo de exemplar?
Las URLs completas pueden contener datos de usuario, tokens y cardinalidad ilimitada. Usa una plantilla de ruta y versión en lista de permitidos; inspecciona los parámetros en una traza o log autorizados y redactados.
¿Qué sucede cuando se descartan todos los exemplars?
Las consultas de métricas y las alertas continúan utilizando series agregadas. Los investigadores pierden el acceso directo de una métrica a una traza, por lo que se deben monitorear las tasas de recepción de exemplars y de éxito de saltos; la ruta de referencia nunca debe bloquear la ingesta de métricas.
¿Cómo demuestras que el muestreo no está sesgado hacia un tenant?
Compara los recuentos de solicitudes, muestras y aciertos por tenant, región, versión y clase de resultado. Establece garantías mínimas y presupuestos máximos, y compara las tasas de aciertos de errores y latencia de cola. Corrige el sesgo con muestreo estratificado en lugar de aumentar la tasa global.