Implementación de trazas con X-Ray

Supervisión y resolución de problemas en AWS

John Q. Martin

Principal Consultant

Descripción general del SDK de X-Ray

 

Datos clave:

  • Lenguajes compatibles: Python, Node.js, Java, .NET, Go, Ruby
  • Dos enfoques: instrumentación automática y manual
  • El SDK se comunica con el daemon por el puerto UDP 2000
  • Nunca habla directamente con la API de X-Ray

 

Automática vs. manual:

Comparación de los enfoques de instrumentación automática y manual del SDK de X-Ray

Supervisión y resolución de problemas en AWS

SDK de Python: configuración con Flask

 

from flask import Flask
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware

app = Flask(__name__)

xray_recorder.configure(
    service='MyFlaskApp',
    sampling=True,
    context_missing='LOG_ERROR',
    daemon_address='127.0.0.1:2000'
)

XRayMiddleware(app, xray_recorder)

 

Cuatro opciones del recorder:

  • service: nombre mostrado en el mapa de servicios
  • sampling: activar/desactivar el muestreo
  • context_missing: LOG_ERROR evita caídas
  • daemon_address: destino al que enviar segmentos

Una vez añadido el middleware, todas las solicitudes entrantes se trazan automáticamente.

Supervisión y resolución de problemas en AWS

Instrumentación automática: Python

 

# Instrumentar todas las librerías compatibles
from aws_xray_sdk.core import patch_all
patch_all()
# O de forma selectiva
from aws_xray_sdk.core import patch
patch(['boto3', 'requests', 'psycopg2'])

 

Librerías compatibles:

Librerías compatibles con la instrumentación automática de X-Ray como boto3 requests y clientes de base de datos

Supervisión y resolución de problemas en AWS

Instrumentación manual: Python

 

Enfoque con decorador:

@xray_recorder.capture('process_order')
def process_order(order_id):
    order = get_order(order_id)
    return process_payment(order)

 

Enfoque con gestor de contexto:

def process_order(order_id):
    with xray_recorder.capture('fetch_order'):
        order = db.query(Order).filter_by(
            id=order_id).first()
    with xray_recorder.capture('process_payment'):
        return payment_service.charge(order.total)
Supervisión y resolución de problemas en AWS

Anotaciones y metadatos en código

 

Añadir anotaciones:

xray_recorder.put_annotation(
    'order_id', order_id)
xray_recorder.put_annotation(
    'user_id', user_id)

 

Añadir metadatos (contexto detallado):

xray_recorder.put_metadata(
    'order_details',
    {'items': order.items,
     'total': order.total})
  • Las anotaciones son índices; los metadatos no
  • Las anotaciones son tipadas; los metadatos pueden ser cualquier JSON
  • Usa índices para filtrar y metadatos para depurar
Supervisión y resolución de problemas en AWS

Gestión de errores en trazas

 

def process_order(order_id):
    try:
        order = get_order(order_id)
        payment = process_payment(order)
        return payment
    except PaymentError as e:
        xray_recorder.put_annotation(
            'error_type', 'payment_failed')
        xray_recorder.put_metadata(
            'error_details',
            {'message': str(e), 'order_id': order_id})
        raise

 

  • Las excepciones dentro de funciones trazadas se capturan automáticamente
  • Añade una anotación con el tipo de error para filtrar en la consola
  • Añade metadatos con los detalles completos del error
  • Vuelve a relanzar siempre; el manejo de errores de tu app debe seguir ejecutándose
Supervisión y resolución de problemas en AWS

SDK de Node.js: configuración con Express

 

const AWSXRay = require('aws-xray-sdk-core');
const xrayExpress = require('aws-xray-sdk-express');
const app = require('express')();

AWSXRay.config([AWSXRay.plugins.EC2Plugin]);

// Abrir segmento para todas las solicitudes entrantes
app.use(xrayExpress.openSegment('MyExpressApp'));

app.get('/api/orders/:id', async (req, res) => {
    const order = await fetchOrder(req.params.id);
    res.json({ order });
});

// Cerrar segmento tras la respuesta
app.use(xrayExpress.closeSegment());

// Instrumentación automática
const AWS = AWSXRay.captureAWS(require('aws-sdk'));
const https = AWSXRay.captureHTTPs(require('https'));
Supervisión y resolución de problemas en AWS

Implementación en Lambda

 

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

patch_all()  # instrumentar llamadas al SDK de AWS

def lambda_handler(event, context):
    xray_recorder.put_annotation(
        'user_id', event['user_id'])

    result = process_user(event['user_id'])

    return {
        'statusCode': 200,
        'body': json.dumps(result)
    }

 

Datos clave:

  • Lambda envía trazas básicas automáticamente si Active Tracing está activado; no hace falta SDK para eso
  • Instala el SDK de X-Ray para añadir subsegmentos, anotaciones e instrumentar llamadas a downstream
  • Actívalo en la consola: Configuration → Monitoring tools
  • O en la plantilla: Tracing: Active
Supervisión y resolución de problemas en AWS

ECS y Fargate: patrón sidecar

 

Estructura de la tarea:

ECS Task
|_ Application Container
|   envía a xray-daemon:2000
|_ X-Ray Daemon Container
    reenvía al servicio X-Ray

Config del contenedor de la app:

xray_recorder.configure(
    service='MyECSApp',
    daemon_address='xray-daemon:2000'
)

 

La definición de tarea incluye:

  • Contenedor del daemon: imagen amazon/aws-xray-daemon, puerto UDP 2000
  • Contenedor de la app: variable AWS_XRAY_DAEMON_ADDRESS=xray-daemon:2000

¿Por qué sidecar?

  • El daemon escala con tus tareas
  • Los fallos quedan aislados por tarea
Supervisión y resolución de problemas en AWS

Instalar el daemon de X-Ray

Instalación por plataforma:

  • Amazon Linux 2
    • sudo yum install -y aws-xray-daemon-3.x.rpm
  • Ubuntu
    • sudo dpkg -i aws-xray-daemon-3.x.deb
  • Windows
    • xray.exe -f cfg.yaml install
  • Docker
    • docker run -p 2000:2000/udp amazon/aws-xray-daemon

Tras la instalación:

sudo systemctl start xray
sudo systemctl enable xray

Qué hace el daemon:

  • Escucha en el puerto UDP 2000
  • Almacena en búfer y agrupa segmentos
  • Reenvía a la API de X-Ray por HTTPS
  • Gestiona reintentos; tu app no necesita hacerlo
Supervisión y resolución de problemas en AWS

Configuración del daemon

 

TotalBufferSizeMB: 24
Concurrency: 8
Region: "us-east-1"
Socket:
  UDPAddress: "127.0.0.1:2000"
  TCPAddress: "127.0.0.1:2000"
Logging:
  LogLevel: "info"
  LogPath: "/var/log/xray/xray-daemon.log"
LocalMode: false

 

  • Tamaño del búfer; aumenta para alto tráfico
  • Concurrency define conexiones paralelas a X-Ray
  • En contenedores, pon la dirección UDP a 0.0.0.0
  • Modo local: true para desarrollo local sin credenciales
Supervisión y resolución de problemas en AWS

Permisos de IAM

 

{
  "Effect": "Allow",
  "Action": [
    "xray:PutTraceSegments",
    "xray:PutTelemetryRecords",
    "xray:GetSamplingRules",
    "xray:GetSamplingTargets",
    "xray:GetSamplingStatisticSummaries"
  ],
  "Resource": "*"
}

 

Enfoque más fácil

Usa la política gestionada AWSXRayDaemonWriteAccess

Asígnala a:

  • Rol de instancia EC2
  • Rol de tarea ECS
  • Rol de ejecución de Lambda

Sin permisos correctos, el daemon se ejecuta pero falla en silencio al enviar segmentos.

Supervisión y resolución de problemas en AWS

Patrones de despliegue del daemon

 

Tres patrones de despliegue del daemon de X-Ray por instancia sidecar y servicio compartido

Supervisión y resolución de problemas en AWS

Resumen de la lección

 

  • SDK: instrumentación automática con patch_all(), manual con decoradores y gestores de contexto
  • Anotaciones (indexadas, buscables) vs. metadatos (detallados, no indexados)
  • Lambda: envía trazas básicas automáticamente; instala el SDK para subsegmentos y llamadas downstream
  • ECS/Fargate: patrón de daemon sidecar
  • Daemon: se configura vía cfg.yaml; necesita la política IAM AWSXRayDaemonWriteAccess
  • Despliegue: por instancia en EC2; sidecar en contenedores
Supervisión y resolución de problemas en AWS

Implementación de trazas con X-Ray

Supervisión y resolución de problemas en AWS

Preparing Video For Download...