Mejores prácticas de APM: guía de lo que se debe y no se debe hacer para profesionales

blog-APM_Best_Practices.jpg

La gestión del rendimiento de aplicaciones (APM) es la práctica de seguir, medir y analizar regularmente el rendimiento y la disponibilidad de las aplicaciones de software. La APM te ayuda a obtener información en entornos de microservicios complejos, que pueden abrumar a los equipos de ingeniería de confiabilidad del sitio (SRE). La información generada crea una experiencia de usuario óptima y logra los resultados empresariales deseados. Es un proceso complejo, pero el objetivo es claro: asegurar que una aplicación funcione sin problemas y cumpla con las expectativas de los usuarios y las empresas. 

Una comprensión clara del funcionamiento de una aplicación y una práctica proactiva de APM son cruciales para mantener aplicaciones de software de alto rendimiento. La APM no debería ser una idea de último momento. Debe considerarse desde el principio. Cuando se implementa de forma proactiva, puedes incorporarla en cómo se ejecuta el software mediante la integración de componentes de monitoreo directamente en la aplicación.

¿Qué es la gestión del rendimiento de aplicaciones?

La gestión del rendimiento de aplicaciones incorpora el monitoreo, el análisis y la gestión de forma continua del rendimiento del backend y frontend de una aplicación. El monitoreo de aplicaciones se está expandiendo y evolucionando, pero la estrategia de APM no debe crearse aislada. Es esencial involucrar a múltiples partes interesadas, expertos en negocios, desarrolladores de aplicaciones y equipos de operaciones. Una estrategia de APM exitosa va más allá del tiempo de actividad o del estado del servidor y se centra en los objetivos a nivel de servicio (SLO) de la aplicación antes de que se conviertan en un problema para los usuarios. 

La implementación moderna de APM implica instrumentar tus aplicaciones para recopilar tres tipos de datos de telemetría: trazas (flujos de solicitudes), métricas (mediciones agrupadas) y logs (eventos discretos). El desafío no es solo recopilar datos, sino recopilar los datos correctos sin afectar el rendimiento.

Conoce más sobre las métricas de observabilidad.

Existen numerosos enfoques de instrumentación, pero la estrategia más eficaz combina la instrumentación automática (para marcos de trabajo y bibliotecas) con la instrumentación manual (para la lógica de negocio). La instrumentación automática con agentes de OpenTelemetry puede capturar el 80 % de tus necesidades de observabilidad con cambios mínimos en el código:

# Auto-instrumentation handles this automatically
@app.route('/api/orders')
def create_order():
    # Add manual span only for critical business logic
    with tracer.start_as_current_span("order.validation") as span:
        span.set_attribute("order.value", order_total)
        if not validate_order(order_data):
            span.set_status(Status(StatusCode.ERROR))
            return 400

  • Qué hacer: comenzar con autoinstrumentación, luego añadir intervalos manuales para operaciones críticas del negocio.

  • Qué no hacer: instrumentar manualmente cada llamada de función; crearás una sobrecarga de rendimiento y ruido.

  • Advertencia: el exceso de instrumentación puede agregar un 15%–20% de latencia. Monitorea tu monitoreo con comparaciones de rendimiento de referencia.

Algunos componentes que una organización o empresa debe considerar al desarrollar una estrategia de APM son:

  • Monitoreo del rendimiento, incluyendo la evaluación de la latencia, los objetivos a nivel de servicio, el tiempo de respuesta, el rendimiento y los volúmenes de solicitudes

  • Seguimiento de errores, incluyendo excepciones, bloqueos y llamadas a la API fallidas 

  • Monitoreo de infraestructura, incluidos el estado y el uso de recursos de servidores, contenedores y entornos de cloud que soportan la aplicación

  • Métricas de la experiencia del usuario, incluidos los tiempos de carga, el rendimiento de la sesión, las rutas de clics y los detalles del navegador o del dispositivo (es importante tener en cuenta que, aunque las métricas del sistema parezcan correctas, los usuarios pueden tener problemas de rendimiento).

Principios clave de una APM eficaz

Los principios del núcleo de una gestión eficaz del rendimiento de las aplicaciones son la visibilidad integral (desde el navegador del usuario hasta la base de datos), el monitoreo y la información en tiempo real y la información contextual, con un enfoque en el usuario y en los objetivos empresariales. La APM puede mejorar la escalabilidad de las aplicaciones al permitir mejoras continuas y aumentar el rendimiento con el tiempo.

  • Qué hacer: implementa dashboards en tiempo real con alertas basadas en SLO en lugar de umbrales arbitrarios.

  • Qué no hacer: no confíes solo en revisiones periódicas de rendimiento o alertas de CPU/memoria; instrumenta métricas de experiencia del usuario.

  • Problema: fatiga de alertas por métricas de sistema de bajo nivel. Concéntrate en los SLO orientados al usuario que indican problemas reales.

Al crear una estrategia de APM, aquí tienes algunos principios clave a considerar:

1. Monitoreo proactivo: prevén problemas antes de que impacten a los usuarios configurando alertas y respondiendo rápidamente a cualquier anomalía. Sin embargo, trata de evitar la fatiga de alertas. Equilibra las alertas automatizadas con la supervisión humana para que no se pasen por alto problemas importantes, enfocándote en los resultados en lugar de en las métricas del sistema. 

2. Información en tiempo real: ve más allá del logging de problemas y permite una toma de decisiones rápida basada en datos en vivo y dashboards en tiempo real que priorizan las transacciones comerciales más críticas. Usa datos de telemetría (logs, métricas y trazas) para parsear tu información de rendimiento.

3. Visibilidad integral: monitorea la aplicación en todo el entorno, el flujo completo de usuarios y todas las capas, desde el frontend hasta el backend.

4. Enfoque centrado en el usuario: prioriza el rendimiento y la experiencia desde la perspectiva del usuario final, considerando los objetivos clave del negocio.

5. Monitoreo del usuario real: el trabajo no se detiene cuando está en manos de tus usuarios. Al monitorear su experiencia, puedes iterar y mejorar en función de sus comentarios.

6. Mejora continua: Usa información para optimizar con el tiempo y descubrir y abordar regularmente problemas no reportados. Los problemas deben abordarse de manera dinámica en lugar de cuando se descubren en las revisiones periódicas de rendimiento. 

7. Propagación de contexto: asegúrate de que el contexto de seguimiento fluya a través de toda la ruta de solicitud, en especial, a través de los límites del servicio:

# Outgoing request - inject context
headers = {}
propagate.inject(headers)
response = requests.post('http://service-b/process', headers=headers)

8. Estrategia de muestreo: Usa el muestreo inteligente para equilibrar la visibilidad con el rendimiento:

  • Muestreo inicial de 1%–10% para servicios de alto tráfico

  • Muestreo del 100 % para errores y solicitudes lentas mediante muestreo final

  • Monitorea la sobrecarga de instrumentación, apunta a un impacto en el rendimiento de <5 %

Mejores prácticas para la implementación de APM

La solución de APM adecuada debe respaldar tu stack tecnológico con un esfuerzo mínimo de instrumentación. OpenTelemetry se ha convertido en el estándar de la industria que proporciona instrumentación independiente del proveedor que funciona en todos los lenguajes:

@RestController
public class OrderController {
    
    @PostMapping("/orders")
    public ResponseEntity<Order> createOrder(@RequestBody OrderRequest request) {
        // Auto-instrumentation captures this endpoint automatically
        // Add custom business context
        Span.current().setAttributes(Attributes.of(
            stringKey("order.value"), String.valueOf(request.getTotal()),
            stringKey("user.tier"), request.getUserTier()
        ));
        
        return ResponseEntity.ok(processOrder(request));
    }
}

  • Qué hacer: implementar estrategias de muestreo y monitorear la sobrecarga de instrumentación en producción.

  • Qué no hacer: usar un muestreo del 100 % para servicios de alto tráfico; afectarás el rendimiento y explotarás los costos de almacenamiento.

  • Trampa: El muestreo inicial puede pasar por alto rastros de errores críticos. Usa el muestreo final para capturar todos los errores mientras reduces el volumen.

Aquí te mostramos cómo hacerlo correctamente:

  • Selecciona la solución de APM adecuada: la herramienta de APM adecuada debe alinearse con la arquitectura de una aplicación y las necesidades de la organización. La solución debe proporcionar a una organización las herramientas y capacidades necesarias para monitorear, rastrear, medir y analizar sus aplicaciones de software. Una empresa puede usar OpenTelemetry, un marco de trabajo observabilidad open source, para instrumentar y recopilar datos de telemetría (trazas, métricas y logs) de las aplicaciones. 

  • Administra la cardinalidad para controlar los costos: los atributos de alta cardinalidad pueden hacer que las métricas sean inutilizables y costosas:
# Good - bounded cardinality
span.set_attribute("user.tier", user.subscription_tier)  # 3-5 values
span.set_attribute("http.status_code", response.status_code)  # ~10 values

# Bad - unbounded cardinality  
span.set_attribute("user.id", user.id)  # Millions of values
span.set_attribute("request.timestamp", now())  # Infinite values
  • Configura alertas inteligentes basadas en SLO en lugar de umbrales arbitrarios. Usa presupuestos de error para determinar cuándo notificar a alguien:
slos:
  - name: checkout_availability
    target: 99.9%
    window: 7d
  - name: checkout_latency  
    target: 95%  # 95% of requests under 500ms
    window: 7d

  • Capacita a los equipos y promueve la colaboración. Una estrategia de APM impacta a una amplia gama de partes interesadas, no solo a los desarrolladores. Asegúrate de involucrar a los equipos de TI y a otros interesados del negocio en la colaboración interdepartamental. Trabajen juntos implementando APM en la configuración de tu organización. Asegúrate de establecer objetivos y KPI claros que se alineen con las necesidades del negocio y consideren la experiencia del usuario. 

  • Revisar y evaluar. Una estrategia de APM sigue evolucionando y cambiando junto con las necesidades de las aplicaciones y del negocio.

Estrategias de monitoreo en APM

Un aspecto clave de una estrategia exitosa de la gestión del rendimiento de aplicaciones es considerar cómo y cuándo utilizar diferentes enfoques de monitoreo. Considerar una combinación de estrategias de monitoreo es vital porque los diferentes componentes de una aplicación, como la experiencia del usuario o la infraestructura, requieren enfoques personalizados para detectar y resolver problemas de manera efectiva. Una estrategia diversa garantiza una cobertura completa, un análisis más rápido, un rendimiento de las aplicaciones más ininterrumpido y usuarios finales más felices.


Existen diferentes enfoques de monitoreo que puedes considerar: 
  • Monitoreo en tiempo real: realiza un seguimiento continuo del rendimiento del sistema en vivo con granularidad de subsegundo. Implementa métricas personalizadas para la lógica empresarial junto con métricas técnicas:
order_processing_duration = Histogram(
    "order_processing_seconds",
    "Time to process orders", 
    ["payment_method", "order_size"]
)

with order_processing_duration.labels(
    payment_method=payment.method,
    order_size=get_size_bucket(order.total)
).time():
    process_order(order)
  • Monitoreo sintético: Simula las interacciones de los usuarios para detectar problemas antes de que los usuarios reales se vean afectados. Crítico para las dependencias externas:
// Synthetic check for critical user flow
const syntheticCheck = async () => {
    const span = tracer.startSpan('synthetic.checkout_flow');
    try {
        await loginUser();
        await addItemToCart();
        await completePurchase();
        span.setStatus({code: SpanStatusCode.OK});
    } catch (error) {
        span.recordException(error);
        span.setStatus({code: SpanStatusCode.ERROR});
        throw error;
    } finally {
        span.end();
    }
};

  • Diagnóstico y perfilado exhaustivos: te ayuda a resolver cuellos de botella de rendimiento complejos, que podrían incluir plugins o herramientas de terceros. Mediante el perfilado de aplicaciones, puedes profundizar en tus datos y analizar cómo funcionan según sus funciones.

  • Trazado distribuido: esencial para arquitecturas de microservicios. Maneja con cuidado la propagación del contexto a través de los límites asíncronos:
# Event-driven systems - propagate context through messages
def publish_order_event(order_data):
    headers = {}
    propagate.inject(headers)
    
    message = {
        'data': order_data,
        'trace_headers': headers  # Preserve trace context
    }
    kafka_producer.send('order-events', message)

Análisis de datos e información de APM

El monitoreo y la recopilación de datos es solo el comienzo. Las empresas necesitan entender cómo interpretar los datos de gestión del rendimiento de aplicaciones para el ajuste y la toma de decisiones.

Identificar tendencias y patrones ayuda a los equipos a detectar problemas de forma proactiva. Usa el análisis de correlación para vincular las quejas de los usuarios con el rendimiento del backend. Mira un ejemplo aquí usando ES|QL (el lenguaje de búsqueda de Elastic):

FROM traces-apm*
| WHERE user.id == "user_12345" 
  AND @timestamp >= "2024-06-06T09:00:00" 
  AND @timestamp <= "2024-06-06T10:00:00"
| EVAL duration_ms = transaction.duration.us / 1000
| KEEP trace.id, duration_ms, transaction.name, service.name, transaction.result
| WHERE duration_ms > 2000
| SORT duration_ms DESC
| LIMIT 10

Detección de cuellos de botella: la APM revela antipatrones de rendimiento comunes, como problemas de n+1 que se pueden ver en el código siguiente. Usa APM para optimizar el código:

# N+1 query problem detected by APM
def get_user_orders_slow(user_id):
    user = User.query.get(user_id)
    orders = []
    for order_id in user.order_ids:  # Each iteration = 1 DB query
        orders.append(Order.query.get(order_id))
    return orders

# Optimized after APM analysis
def get_user_orders_fast(user_id):
    return Order.query.filter(Order.user_id == user_id).all()  # Single query

Correlacionar métricas y vincular las quejas de los usuarios con los datos de rendimiento del backend, incluidos los datos históricos, revela cómo interactúan las distintas partes del sistema. Esto puede ayudar a los equipos a diagnosticar con precisión las causas raíz y comprender el impacto completo de los problemas de rendimiento.

Automatizar el análisis de la causa raíz y utilizar herramientas basadas en IA/machine learning, como AIOps ayuda a acelerar el diagnóstico y la resolución al identificar el origen de los problemas, reducir el tiempo de inactividad y liberar recursos.

Es importante utilizar una visión integral de tus datos para informar decisiones futuras. Cuantos más datos tengas, más podrás aprovecharlos.

  • Haz lo siguiente: Usa trazas distribuidas para identificar el servicio y la operación específicos que están causando ralentizaciones.

  • Qué no hacer: no asumas que la correlación significa causalidad; verifica con datos de perfilado a nivel de código.

  • Problema: los sistemas heredados a menudo aparecen como cajas negras en las trazas. Usa la correlación de logs y los intervalos sintéticos para mantener la visibilidad.

Patrones de implementación avanzados

Los entornos de producción complejos presentan desafíos únicos que requieren estrategias de implementación avanzadas. Esta sección abarca enfoques prácticos para manejar arquitecturas políglotas, la integración de sistemas heredados y el análisis de correlación sofisticado.

Propagación del contexto en entornos políglotas: Mantener el contexto de seguimiento a través de diferentes lenguajes y marcos de trabajo requiere atención explícita a los mecanismos de propagación:

// Java - Auto-propagation with Spring Cloud
@PostMapping("/orders")
public ResponseEntity<Order> createOrder(@RequestBody OrderRequest request) {
    Span.current().setAttributes(Attributes.of(
        stringKey("order.type"), request.getOrderType(),
        longKey("order.value"), request.getTotalValue()));
    
    // OpenFeign automatically propagates context to downstream services
    return paymentClient.processPayment(request.getPaymentData());}
// Go - Manual context extraction and propagation
func processHandler(w http.ResponseWriter, r *http.Request) {
    ctx := otel.GetTextMapPropagator().Extract(r.Context(), 
                                              propagation.HeaderCarrier(r.Header))
    ctx, span := tracer.Start(ctx, "process_payment")
    defer span.End()
    // Continue with trace context maintained}

Integración de sistemas heredados: crea puentes de observabilidad para sistemas que no se pueden instrumentar directamente:

# Synthetic spans with correlation IDs for mainframe calls
with tracer.start_as_current_span("mainframe.account_lookup") as span:
    correlation_id = format(span.get_span_context().trace_id, '032x')
    
    logger.info("CICS call started", extra={
        "correlation_id": correlation_id,
        "trace_id": span.get_span_context().trace_id
    })
    
    result = call_mainframe_service(account_data, correlation_id)
    span.set_attribute("account.status", result.status)

Análisis avanzado de trazas con ES|QL: Vincula las quejas de los usuarios con el rendimiento del backend usando el lenguaje de búsqueda de Elastic:

-- Find slow requests during complaint timeframe
FROM traces-apm*
| WHERE user.id == "user_12345" AND @timestamp >= "2024-06-06T09:00:00"
| EVAL duration_ms = transaction.duration.us / 1000
| WHERE duration_ms > 2000
| STATS avg_duration = AVG(duration_ms) BY service.name, transaction.name
| SORT avg_duration DESC

-- Correlate errors across service boundaries
FROM traces-apm*
| WHERE trace.id == "44b3c2c06e15d444a770b87daab45c0a"
| EVAL is_error = CASE(transaction.result == "error", 1, 0)
| STATS error_rate = SUM(is_error) / COUNT(*) * 100 BY service.name
| WHERE error_rate > 0

Patrones de arquitectura orientados a eventos: Propaga explícitamente el contexto a través de los encabezados de los mensajes para el procesamiento asíncrono:

# Producer - inject context into message
headers = {}
propagate.inject(headers)
message = {
    'data': order_data,
    'trace_headers': headers  # Preserve trace context
}
await kafka_producer.send('order-events', message)

# Consumer - extract and continue trace
trace_headers = message.get('trace_headers', {})
context = propagate.extract(trace_headers)
with tracer.start_as_current_span("order.process", context=context):
    await process_order(message['data'])

  • Qué hacer: usar ES|QL para análisis de trazas complejas que los dashboards tradicionales no pueden manejar.

  • Qué no hacer: intentar instrumentar sistemas heredados directamente; usar ID de correlación e intervalos sintéticos.

  • Problema: las colas de mensajes y el procesamiento asíncrono rompen el contexto de rastreo a menos que se propaguen explícitamente a través de los encabezados.

  • Información clave: la instrumentación perfecta no siempre es posible. El uso estratégico de ID de correlación, intervalos sintéticos y consultas inteligentes proporciona una observabilidad completa incluso en entornos híbridos complejos.

APM para optimización del rendimiento con Elastic Observability

Elastic Observability facilita la implementación de una estrategia de gestión del rendimiento de aplicaciones al ofrecer una observabilidad unificada, combinando datos de rendimiento de aplicaciones con logs, métricas y trazas en una única plataforma poderosa. Recopilar datos con las Distribuciones de OpenTelemetry de Elastic (EDOT) hace que sea rápido y sencillo comenzar a recolectar datos de APM. 

Los desarrolladores pueden configurar alertas para anomalías, usar el trazado distribuido para optimizar servicios o transacciones específicos, reducir la latencia y mejorar la estabilidad del rendimiento con Elastic mediante el balanceo de carga y el almacenamiento en caché. 

Mediante el perfilado de código, los equipos pueden identificar puntos críticos de rendimiento, rutas de código ineficientes, fugas de memoria u operaciones que consumen muchos recursos y ralentizan las aplicaciones. Las empresas pueden crear dashboards personalizados para realizar un seguimiento de los KPI, lo que contribuye en última instancia a mejores resultados empresariales.

Explora Elastic Observability Labs para ver más contenido técnico sobre observabilidad.

Recursos adicionales de APM 

El lanzamiento y el momento de cualquier característica o funcionalidad descrita en esta publicación quedan a exclusivo criterio de Elastic. Es posible que cualquier característica o funcionalidad que no esté disponible en este momento no se lance a tiempo o no se lance en absoluto.