Skip to main content
16 jul 2026correlation ids trazabilidad distribuida k6

Por Performate

Correlation IDs y trazabilidad distribuida en pruebas de carga: corridas k6 depurables

Propaga headers de contexto de traza desde k6, alinea con spans del backend y depura colas de latencia más rápido.

Tu prueba soak muestra p99 de checkout a 2,4 segundos durante una hora—pero cuando on-call abre el dashboard APM, cada span parece tráfico anónimo desde 10.0.0.0. Sin contexto de traza, los fallos bajo carga se vuelven arqueología: grep en logs, adivinar números de VU y esperar que alguien guardó el timestamp correcto.

Los picos de latencia se vuelven accionables cuando cada iteración de k6 emite traceparent y baggage opcional compatibles con OpenTelemetry (W3C Trace Context). En esta guía verás por qué los correlation IDs cambian la respuesta a incidentes bajo carga, cómo generar headers de traza válidos en k6, y qué checks de observabilidad demuestran que tu generador y backend acuerdan la misma traza.

Por qué las pruebas de carga necesitan contexto de traza—no solo tags

Los tags de k6 separan métricas por ruta y escenario; el APM separa spans por trace ID. Sin un puente entre ambos, optimizas a ciegas:

  • Tráfico anónimo: los backends agrupan generadores en una cuenta de servicio—los spans carecen del contexto de iteración que necesitas.
  • La cola de latencia oculta causalidad: picos p99 pueden ser waits de BD, saltos de mesh o cachés frías—los tags solos no los distinguen (análisis de cuellos de botella).
  • Los soak corren largo: fugas de memoria y acumulación en colas aparecen tras decenas de minutos; necesitas trace IDs duraderos por familia de request (playbook soak).
  • Flujos multi-salto: checkout puede tocar auth, inventario y pago—un correlation ID debe coser el grafo.

Piensa en los headers de traza como códigos de barras en cada request sintético: los escáneres downstream deben leer el mismo ID que imprimió tu herramienta de carga.

Cuando las métricas dicen lento pero los logs no dicen nada

Los equipos suelen añadir X-Request-Id manualmente mientras el service mesh espera traceparent W3C. Los gateways eliminan headers desconocidos; el APM muestra trazas parciales. Alinea con el estándar que exporta tu plataforma—Jaeger, Tempo, Datadog y New Relic ingieren contexto W3C cuando está configurado (tags de observabilidad).

Implementación práctica con k6: traceparent W3C por iteración

Genera un trace ID fresco por request (o por iteración de VU en flujos multi-paso), formatea traceparent correctamente y pasa baggage opcional con metadata de carga como vu e iter. El middleware del backend debe continuar la traza—no iniciar un root span nuevo en silencio.

Ejemplo de script (ilustrativo—no listo para producción). El fragmento usa URLs, tokens y números SLO ficticios. Adapta base URL, auth, payloads y umbrales a tu entorno.

Qué demuestra este ejemplo:

  • traceparent W3C válido: versión 00, trace ID hex de 32 chars, span ID hex de 16 chars, flag sampled 01.
  • Baggage para metadata de carga: vu, iter y scenario propagan cuando tu collector soporta baggage W3C.
  • Header de correlación legacy: X-Correlation-Id opcional para servicios aún sin OpenTelemetry.
  • Métricas etiquetadas + trace IDs: tags de ruta k6 para resúmenes; trace IDs para flame graphs APM en la misma corrida.
import http from 'k6/http';
import { check, sleep } from 'k6';
import { randomBytes } from 'k6/crypto';

const BASE = __ENV.API_BASE || 'https://staging.example.com';
const TOKEN = __ENV.TOKEN || 'staging-token-replace-me';

function hex(bytes) {
  return Array.from(new Uint8Array(bytes))
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('');
}

function traceparent() {
  const traceId = hex(randomBytes(16)); // 32 hex chars
  const spanId = hex(randomBytes(8)); // 16 hex chars
  return `00-${traceId}-${spanId}-01`;
}

function correlationId() {
  return `k6-${__VU}-${__ITER}-${hex(randomBytes(4))}`;
}

function traceHeaders() {
  const tp = traceparent();
  const cid = correlationId();
  return {
    traceparent: tp,
    tracestate: 'k6=load',
    baggage: `vu=${__VU},iter=${__ITER},scenario=checkout`,
    'X-Correlation-Id': cid,
  };
}

export const options = {
  scenarios: {
    traced_checkout: {
      executor: 'constant-arrival-rate',
      rate: Number(__ENV.CHECKOUT_RPS || 8),
      timeUnit: '1s',
      duration: '10m',
      preAllocatedVUs: 10,
      maxVUs: 40,
      tags: { route: 'checkout', trace: 'w3c' },
      exec: 'checkoutTraced',
    },
  },
  thresholds: {
    'http_req_duration{route:checkout}': ['p(95)<900', 'p(99)<1400'],
    http_req_failed: ['rate<0.01'],
  },
};

export function checkoutTraced() {
  const body = JSON.stringify({ sku: `SKU-${__VU}`, qty: 1 });
  const headers = {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${TOKEN}`,
    ...traceHeaders(),
  };

  const res = http.post(`${BASE}/checkout`, body, {
    headers,
    tags: { route: 'checkout', trace: 'w3c' },
  });

  check(res, { 'checkout 2xx': (r) => r.status >= 200 && r.status < 300 });
  sleep(0.5);
}

Patrones que funcionan

  • Una traza por journey de usuario cuando los flujos llaman auth y luego checkout—reutiliza traceparent entre pasos en la misma iteración.
  • Filtra APM por baggage vu= para saltar de outliers del resumen k6 a flame graphs exactos.
  • Depura PII del baggage antes de exportar trazas a tenants compartidos (datos de prueba GDPR).
  • Combina con sampling específico de env para que collectors de staging retengan 100% de trazas de carga durante investigaciones (variables de entorno).

Anti-patrones a evitar

  • Reutilizar un X-Request-Id estático para todos los VUs—colapsa miles de requests en una traza lógica.
  • Enviar traceparent mal formado (hex de longitud incorrecta)—el APM descarta contexto en silencio.
  • Loguear trace IDs completos en artefactos CI públicos cuando las trazas contienen payloads de clientes.
  • Ignorar sidecars de mesh que sobrescriben headers de traza salvo que inyectes en el salto correcto.

Pro tip (comando de ejemplo): la línea siguiente exporta JSON de resumen k6 junto a una corrida que correlacionarás manualmente en APM—no es flag obligatorio en cada soak.

k6 run traced-checkout.js --summary-export=run-summary.json --tag git_sha=$GIT_SHA

Qué demuestra este comando: los resúmenes exportados incluyen tags de escenario y git SHA—pega timestamps de ventanas lentas en búsqueda APM con baggage git_sha o marcadores de deploy coincidentes.

Marco de decisión: request ID vs traza W3C completa

SituaciónAcción recomendada
Monolito con solo correlación en logsX-Correlation-Id + logs estructurados; migra a W3C cuando llegue APM
OpenTelemetry / mesh ya desplegadotraceparent + baggage en cada request k6; verifica retención del collector
Flujos multi-paso checkout/authUn trace ID por iteración en todas las llamadas HTTP del default function
Soak largo buscando fugasTraza única por request; filtra outliers p99 en APM por ventana temporal + tag de ruta
Datos regulados en payloadsMinimiza baggage; depura IDs de logs exportados (datos GDPR)

Usa traceparent W3C si tu backend o service mesh ya exporta OpenTelemetry—es el default en plataformas API modernas.

Usa headers de correlación legacy si servicios antiguos solo loguean X-Request-Id—pero planifica migración antes de que headers duales confundan a on-call.

Usa metadata en baggage si tu collector lo soporta y necesitas mapear __VU/__ITER de k6 a spans sin adivinar timestamps.

Observabilidad, documentación y próximos pasos

La propagación de trazas solo ayuda cuando collectors, retención y runbooks coinciden. Antes de escalar tráfico:

  • Verifica que APM de staging retenga trazas durante todo el soak—no solo los primeros quince minutos.
  • Documenta qué headers pasan los gateways; listas de strip han bloqueado traceparent antes.
  • Añade paso en runbook: «filtrar trazas por ventana temporal route:checkout, abrir trace IDs del peor p99».
  • Confirma que IPs del generador están allowlisted sin forzar todos los spans a un nodo de servicio anónimo.
  • Archiva JSON de resumen k6, git SHA y tags de escenario por corrida para que postmortems enlacen métricas y trazas.

Cómo Performate simplifica pruebas de carga alineadas a trazas

Escribir headers de traza a mano en cada script exportado deriva cuando alguien copia una plantilla vieja sin baggage. Abajo un ejemplo concreto de flujo para checkout trazado bajo soak.

Ejemplo: corridas etiquetadas que mapean a APM

  1. Importa requests de checkout desde Postman u OpenAPI—el mismo flujo que soakas por fugas de memoria. Problema resuelto: una definición de request; sin bloques HTTP duplicados «trazado» vs «sin trazar».
  2. Añade headers custom en el panel de escenario: notas placeholder de traceparent y tracestate=k6=load estático donde documentas estándares—or exporta y añade el helper una vez. Problema resuelto: los revisores ven intención de headers antes del export, no enterrada en git.
  3. Aplica tags route:checkout y trace:w3c en el escenario para que resúmenes k6 coincidan con filtros APM. Problema resuelto: compara colas de métricas y de trazas con el mismo vocabulario.
  4. Corre soak de 10 minutos y exporta reporte integrado más script k6 para CI. Problema resuelto: comparte un enlace con on-call que incluye tags de escenario y fallos de umbral.
  5. Pega timestamps de ventana lenta en APM y busca por correlation ID o baggage vu= de la peor iteración. Problema resuelto: minutos hasta causa raíz en lugar de arqueología en logs.
  6. Re-exporta tras cambios de headers para que CI y desktop queden alineados—especialmente cuando la plataforma mejora soporte baggage W3C.

Ese flujo mapea al cta: corridas etiquetadas donde los correlation IDs mapean limpio a trazas APM.

Conclusión

Las pruebas de carga sin contexto de traza optimizan agregados, no incidentes. Propaga traceparent W3C, añade baggage seguro con metadata k6 y verifica que tu mesh reenvíe headers antes del próximo soak.

Corre un soak de checkout trazado esta semana—filtra APM por el peor minuto p99 y confirma que puedes abrir un flame graph de un checkout sintético sin adivinar números de VU.

Try Performate free | Reservar demo | Escenarios k6

¿Listo para optimizar el rendimiento de tu API?

Usa Performate para compartir corridas etiquetadas donde los correlation IDs mapean limpio a trazas APM.

← Volver a todas las entradas