Dos caras de una misma moneda: Unificar las pruebas y el monitoreo mediante monitoreo sintético

digital-experience-monitoring.jpg

Históricamente, desarrollo de software y SRE han trabajado en silos con distintas prioridades y perspectivas culturales. El objetivo de DevOps es establecer prácticas comunes y complementarias en el desarrollo de software y las operaciones. Sin embargo, para algunas organizaciones la verdadera colaboración es poco frecuente, y todavía nos falta mucho para crear sociedades de DevOps efectivas.

Más allá de los desafíos culturales, uno de los motivos más habituales de esta desconexión es el uso de distintas herramientas para alcanzar objetivos similares; un buen ejemplo, pruebas integrales frente a monitoreo sintético

En este blog se comparte una visión general de estas técnicas. Con el repositorio de ejemplo carlyrichmond/synthetics-replicator, también mostraremos cómo Playwright, @elastic/synthetics y GitHub Actions pueden combinar fuerzas con Elastic Synthetics y el registrador para unir los equipos de desarrollo y SRE en la validación y el monitoreo de la experiencia de usuario para una aplicación web simple hospedada en un proveedor como Netlify.

Elastic introdujo recientemente el monitoreo sintético y, como destacamos en nuestro blog anterior,puede reemplazar las pruebas integrales por completo. Unificar en torno a una sola herramienta para validar el flujo de trabajo del usuario de forma temprana brinda un lenguaje común que permite recrear los problemas del usuario a fin de validar las soluciones.

Monitoreo sintético frente a pruebas integrales

Si las herramientas de desarrollo y operaciones se enfrentan, es difícil unificar sus diferentes culturas. Tener en cuenta las definiciones de estos enfoques muestra que, de hecho, apuntan a lograr el mismo objetivo.

Las pruebas integrales son un conjunto de pruebas que recrean el recorrido del usuario, incluidos los clics, lo que escribió el usuario y por dónde navegó. Si bien muchos sostienen que lo importante es probar la integración de las capas de una aplicación de software, lo que las pruebas integrales emulan en el flujo de trabajo del usuario. Mientras que el monitoreo sintético, específicamente un subconjunto conocido como monitoreo de navegador, es una práctica de monitoreo de rendimiento de aplicaciones que emula el recorrido del usuario en una aplicación. 

Ambas técnicas emulan el recorrido del usuario. Si usamos herramientas que salden la brecha operativa y de los desarrolladores, podemos trabajar juntos para elaborar pruebas que también brinden monitoreo de producción en nuestras aplicaciones web.

Creación de los recorridos de los usuarios

Cuando un flujo de trabajo de usuario nuevo, o un conjunto de características que logran un objetivo clave, está en desarrollo en nuestra aplicación, los desarrolladores pueden usar @elastic/synthetics para crear los recorridos. El armazón del proyecto inicial se puede generar con la utilidad init una vez instalada, como en el ejemplo siguiente. Ten en cuenta que Node.js debe instalarse antes de usar esta utilidad.

npm install -g @elastic/synthetics
npx @elastic/synthetics init synthetics-replicator-tests

Antes de iniciar el asistente, asegúrate de tener la información del cluster de Elastic y la integración Elastic Synthetics en el cluster. Necesitarás lo siguiente: 

  1. La gestión de monitoreo debe estar habilitada en la app Elastic Synthetics conforme a los requisitos previos en la documentación de primeros pasos
  2. La Cloud ID del cluster de Elastic Cloud, si usas Elastic Cloud. Como alternativa, si usas hospedaje en las instalaciones, necesitas introducir tu endpoint de Kibana.
  3. Una clave de API generada desde tu cluster. Hay un acceso directo en la configuración de la aplicación Synthetics para generar esta clave bajo la pestaña Project API Keys (Claves de API del proyecto), como se muestra en la documentación.

Este asistente te guiará y generará un proyecto de muestra con recorridos de monitoreo de ejemplo y configuración, con una estructura similar a la siguiente:

prueba de replicadores de synthetics

A los desarrolladores web, la mayoría de los elementos, como los archivos README, package.json y de bloqueo, les resultarán conocidos. La configuración principal para tus monitores está disponible en synthetics.config.ts, como se muestra a continuación. Esta configuración puede modificarse para incluir una configuración específica para el desarrollo y la producción. Esto es fundamental para combinar fuerzas y reutilizar los mismos monitores para las pruebas integrales y para permitir que se usen los recorridos como monitores de producción y pruebas integrales. Aunque no se incluyen en este ejemplo, pueden incluirse los detalles de ubicaciones privadas en caso de que prefieras monitorear desde tu propia instancia de Elastic en lugar de hacerlo desde la infraestructura de Elastic.

import type { SyntheticsConfig } from '@elastic/synthetics';

export default env => {
  const config: SyntheticsConfig = {
    params: {
      url: 'http://localhost:5173',
    },
    playwrightOptions: {
      ignoreHTTPSErrors: false,
    },
    /**
     * Configure global monitor settings
     */
    monitor: {
      schedule: 10,
      locations: ['united_kingdom'],
      privateLocations: [],
    },
    /**
     * Project monitors settings
     */
    project: {
      id: 'synthetics-replicator-tests',
      url: 'https://elastic-deployment:port',
      space: 'default',
    },
  };
  if (env === 'production') {
    config.params = { url: 'https://synthetics-replicator.netlify.app/' }
  }
  return config;
};

Escritura del primer recorrido

Si bien la configuración anterior aplica a todos los monitores en el proyecto, puede anularse para una prueba dada.

import { journey, step, monitor, expect, before } from '@elastic/synthetics';

journey('Replicator Order Journey', ({ page, params }) => {
  // Only relevant for the push command to create
  // monitors in Kibana
  monitor.use({
    id: 'synthetics-replicator-monitor',
    schedule: 10,
  });

// journey steps go here

});

La envoltura @elastic/synthetics expone muchos métodos de prueba estándares como las construcciones before y after que permiten la configuración y el desmantelado de propiedades típicas en las pruebas, al igual que soporte para muchos métodos helper de confirmación comunes. Hay una lista completa de métodos expect compatibles en la documentación. El objeto page de Playwright también se expone, lo que nos permite realizar todas las actividades esperadas proporcionadas en la API, por ejemplo, ubicar elementos de página y simular eventos de usuarios, como clics, que se muestran en el ejemplo siguiente.

import { journey, step, monitor, expect, before } from '@elastic/synthetics';

journey('Replicator Order Journey', ({ page, params }) => {
  // monitor configuration goes here
 
  before(async ()=> {
    await page.goto(params.url);
  });

  step('assert home page loads', async () => {
    const header = await page.locator('h1');
    expect(await header.textContent()).toBe('Replicatr');
  });

  step('assert move to order page', async () => {
    const orderButton = await page.locator('data-testid=order-button');
    await orderButton.click();
    
    const url = page.url();
    expect(url).toContain('/order');

    const menuTiles = await page.locator('data-testid=menu-item-card');
    expect(await menuTiles.count()).toBeGreaterThan(2);
  });


// other steps go here


});

Como puedes ver en el ejemplo anterior, también se exponen las construcciones journey y step. Esta construcción refleja la práctica de desarrollo impulsado por el comportamiento (BDD) de mostrar el recorrido del usuario a través de la aplicación en pruebas.

Los desarrolladores pueden ejecutar pruebas en una aplicación que se ejecuta de forma local como parte del desarrollo de la característica para ver qué pasos se completan correctamente o fallan en el flujo de trabajo del usuario. En el ejemplo siguiente, el comando de inicio de servidor local está resaltado en azul en la parte superior. El comando de ejecución de monitor se destaca en rojo más abajo.

Como puedes ver con las tildes verdes junto a cada paso del recorrido, todas las pruebas se completaron correctamente. ¡Vamos!

Establecer puertas en los pipelines de CI

Es importante usar la ejecución de los monitores en tu pipeline de CI como una puerta hacia la combinación de los cambios de código y la carga de la versión nueva de los monitores. Cada uno de los trabajos en nuestro flujo de trabajo de GitHub Actions se debatirá en esta sección y en la posterior.

El trabajo de prueba activa una instancia de prueba y ejecuta nuestros recorridos de usuario para validar los cambios, como se muestra a continuación. Este paso debería ejecutarse en las solicitudes de extracción para validar los cambios del desarrollador, además de en las de envío.

jobs:   
  test:
    env:
      NODE_ENV: development
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm install
      - run: npm start &
      - run: "npm install @elastic/synthetics && SYNTHETICS_JUNIT_FILE='junit-synthetics.xml' npx @elastic/synthetics . --reporter=junit"
        working-directory: ./apps/synthetics-replicator-tests/journeys
      - name: Publish Unit Test Results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: always()
        with:
          junit_files: '**/junit-*.xml'
          check_name: Elastic Synthetics Tests

Ten en cuenta que, a diferencia de la ejecución del recorrido en nuestra máquina local, usamos la opción --reporter=junit al ejecutar npx @elastic/synthetics para brindar visibilidad de que completamos correctamente los recorridos al trabajo de CI o que, a veces, lamentablemente fallamos.

Cargar automáticamente los monitores

A fin de garantizar que los monitores más recientes estén disponibles en Elastic Uptime, se recomienda enviar los monitores de forma programática como parte del flujo de trabajo de CI, tal como en la tarea de ejemplo siguiente. Nuestro flujo de trabajo tiene un segundo trabajo push, que se muestra a continuación, el cual depende de la ejecución correcta de nuestro trabajo test que carta tus monitores al cluster. Ten en cuenta que este trabajo está configurado en nuestro flujo de trabajo para ejecutarse al enviarse a fin de asegurar que los cambios se hayan validado en lugar de generado en una solicitud de extracción.

jobs:   
  test: …
  push:
    env:
      NODE_ENV: production
      SYNTHETICS_API_KEY: ${{ secrets.SYNTHETICS_API_KEY }}
    needs: test
    defaults:
      run:
        working-directory: ./apps/synthetics-replicator-tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm install
      - run: npm run push

El asistente @elastic/synthetics init genera un comando de envío por ti cuando creas el proyecto que puede desencadenarse desde la carpeta del proyecto. Esto se muestra a continuación en la configuración de steps y working_directory. El comando de envío requiere la clave de API de tu cluster de Elastic, que debería estar almacenada como secreto en un almacén de confianza y a la que debería hacerse referencia a través de una variable de entorno de flujo de trabajo. También es fundamental que los monitores continúen luego de enviar la configuración de monitores actualizada a tu instancia de Elastic Synthetics a fin de evitar la interrupción del monitoreo de producción. A diferencia de las pruebas integrales que se ejecutan en un entorno de prueba, los monitores interrumpidos afectan las actividades de SRE y, por lo tanto, se deben validar todos los cambios. Por este motivo, se recomienda aplicar una dependencia a tu paso de prueba a través de la opción needs.

Monitorear con Elastic Synthetics

Una vez cargados los monitores, brindan un punto de control regular para los equipos de SRE en cuanto a si el flujo de trabajo del usuario funciona como está previsto; no solo porque se ejecutarán de forma regular conforme a la configuración para el proyecto y las pruebas individuales, como se mostró antes, sino también debido a la posibilidad de comprobar el estado de todas las ejecuciones de los monitores y de ejecutarlas a demanda.

La pestaña Monitors Overview (Visión general de monitores) nos brinda una vista inmediata del estado de todos los monitores configurados, además de la capacidad de ejecutar el monitor manualmente a través del menú de elipsis de la tarjeta.

monitores de elastic observability

Desde la pantalla Monitor, también podemos navegar a una visión general de una ejecución de monitor individual para investigar fallas.

detalles de ejecución de prueba

El otro superpoder de monitoreo que tienen ahora los SRE es la integración entre estos monitores y las herramientas conocidas que los SRE ya usan para examinar el rendimiento y la disponibilidad de aplicaciones, como APM, métricas y logs. El menú acertadamente llamado Investigate (Investigar) permite una navegación sencilla mientras los SRE realizan investigaciones de fallos o cuellos de botella potenciales.

También hay un equilibrio entre hallar problemas y recibir automáticamente notificaciones de problemas potenciales. Los SRE que ya están acostumbrados a establecer reglas y umbrales para la notificación de problemas se alegrarán de saber que esto también es posible en los monitores de navegadores. A continuación se muestra la edición de una regla de ejemplo.

reglas de elastic observability

El estado de los monitores de navegadores puede configurarse no solo para que considere si algún monitor individual o colectivo ha quedado fuera de servicio varias veces (como en la comprobación de estado anterior), sino también para que evalúe la disponibilidad general a partir del porcentaje de comprobaciones completadas correctamente en un período dado. A los SRE no solo les interesa reaccionar ante problemas de una forma de gestión de producción tradicional; también quieren mejorar la disponibilidad de las aplicaciones.

Registrar los flujos de trabajo de los usuarios

La limitación de generar pruebas integrales a través del ciclo de vida de desarrollo es que, en ocasiones, a los equipos se les pasan cosas por alto, y el conjunto de herramientas anterior está centrado en los equipos de desarrollo. A pesar de las buenas intenciones de desarrollar un producto intuitivo con equipos multidisciplinarios, los usuarios pueden usar las aplicaciones de formas no previstas. Además, los monitores escritos por desarrolladores solo abarcarán esos flujos de trabajo previstos y darán alerta cuando los monitores fallen en producción o cuando comiencen a comportarse de manera diferente si se les aplica la detección de anomalías.

Cuando surgen problemas para los usuarios, resulta útil recrear ese problema en el mismo formato de nuestros monitores. También es importante aprovechar la experiencia de los SRE para generar recorridos de usuarios, dado que tendrán en cuenta de forma intuitiva los casos de fallas en los que los desarrolladores pueden tener problemas y se enfocarán en los casos exitosos. Sin embargo, no todos los SRE cuentan con la experiencia o confianza para escribir estos recorridos con Playwright y @elastic/synthetics.

Video thumbnail

Aquí es donde entra en escena el registrador de Elastic Synthetics. En el video anterior se muestra detalladamente cómo se puede usar para registrar los pasos de un recorrido de usuario y exportarlos a un archivo JavaScript a fin de incluirlos en tu proyecto de monitores. Esto resulta útil como retroalimentación en la fase de desarrollo y para probar las soluciones desarrolladas a fin de resolver el problema. No es posible adoptar este enfoque a menos que combinemos fuerzas para usar estos monitores juntos.

¡Pruébalo!

A partir de la versión 8.8, @elastic/synthetics y la app Elastic Synthetics están disponibles para el público en general, y el registrador confiable está en versión beta. Comparte tus experiencias saldando la brecha entre desarrolladores y operaciones con Synthetic Monitoring a través de la categoría Uptime (Tiempo de actividad) en los foros de debate de la comunidad o mediante Slack.

¡Feliz monitoreo!

Publicado originalmente el 6 de febrero de 2023; actualizado el 23 de mayo de 2023.