Dois lados da mesma moeda: a união de teste e monitoramento com o monitoramento sintético

digital-experience-monitoring.jpg

Historicamente, o desenvolvimento de software e o SRE sempre trabalharam de forma isolada, com diferentes perspectivas culturais e prioridades. O objetivo do DevOps é estabelecer práticas comuns e complementares no desenvolvimento e nas operações de software. No entanto, para algumas organizações, a verdadeira colaboração é rara e ainda temos um longo caminho a percorrer para construir parcerias eficazes em DevOps.

Fora os desafios culturais, um dos motivos mais comuns para essa desconexão é o uso de ferramentas diferentes para alcançar objetivos semelhantes — no caso, teste de ponta a ponta (e2e, de end-to-end) versus monitoramento sintético

Este post do blog compartilha uma visão geral dessas técnicas. Usando o repositório de exemplo carlyrichmond/synthetics-replicator, também mostraremos como o Playwright, o @elastic/synthetics e o GitHub Actions podem combinar forças com o Elastic Synthetics e o gravador para unir as equipes de desenvolvimento e SRE na validação e no monitoramento da experiência do usuário para uma aplicação web simples hospedada em um provedor como a Netlify.

A Elastic recentemente introduziu o monitoramento sintético e, conforme destacamos em nosso post do blog anterior, ele pode substituir totalmente os testes e2e. A união em torno de uma única ferramenta para validar o fluxo de trabalho do usuário no início fornece uma linguagem comum para recriar os problemas do usuário a fim de validar as correções.

Monitoramento sintético X testes e2e

Se as ferramentas de desenvolvimento e operações estão em guerra, é difícil unificar suas diferentes culturas. Considerar as definições dessas abordagens mostra que elas, de fato, visam atingir o mesmo objetivo.

Os testes e2e são um conjunto de testes que recriam o caminho do usuário, incluindo cliques, entrada de texto do usuário e navegações. Embora muitos argumentem que se trata de testar a integração das camadas de uma aplicação de software, é o fluxo de trabalho do usuário que os testes e2e emulam. Enquanto isso, o monitoramento sintético, especificamente um subconjunto conhecido como monitoramento de navegador, é uma prática de monitoramento de performance de aplicação que emula o caminho do usuário por uma aplicação. 

Ambas as técnicas emulam o caminho do usuário. Se usarmos ferramentas que cruzarem a divisão entre operacional e desenvolvedor, poderemos trabalhar juntos para criar testes que também poderão fornecer monitoramento de produção em nossas aplicações web.

Criação de jornadas do usuário

Quando um novo fluxo de trabalho do usuário ou um conjunto de recursos que atingem um objetivo principal está em desenvolvimento em nossa aplicação, os desenvolvedores podem usar o @elastic/synthetics para criar jornadas do usuário. A estrutura inicial do projeto pode ser gerada com o utilitário init após a instalação, como no exemplo abaixo. Observe que o Node.js deve ser instalado antes do uso desse utilitário.

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

Antes de iniciar o assistente, certifique-se de ter as informações do cluster da Elastic e a integração do Elastic Synthetics definidas no seu cluster. Requisitos: 

  1. O Monitor Management deve ser habilitado no app Elastic Synthetics de acordo com os pré-requisitos da documentação de primeiros passos
  2. O Cloud ID do cluster do Elastic Cloud, se estiver usando o Elastic Cloud. Como alternativa, se você estiver usando hospedagem no local, precisará inserir seu endpoint do Kibana.
  3. Uma chave de API gerada do seu cluster. Existe um atalho nas configurações do app Synthetics para gerar essa chave na guia Project API Keys (Chaves da API do projeto), conforme mostrado na documentação.

Este assistente guiará você e gerará um projeto de amostra contendo as jornadas de configuração e do monitor de exemplo, com uma estrutura semelhante à abaixo:

testes de replicadores do synthetics

Para desenvolvedores web, a maioria dos elementos, como o README, o package.json e os arquivos de bloqueio serão familiares. A configuração principal dos seus monitores está disponível em synthetics.config.ts, conforme mostrado abaixo. Essa configuração pode ser alterada para incluir a configuração específica para produção e desenvolvimento. Isso é essencial para combinar forças e reutilizar os mesmos monitores para testes e2e, permitindo que qualquer jornada seja usada como monitores de produção e testes e2e. Embora não esteja neste exemplo, detalhes de locais privados poderão ser incluídos se você preferir monitorar da sua própria instância dedicada do Elastic em vez da infraestrutura do 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;
};

Escrevendo sua primeira jornada

Embora a configuração acima se aplique a todos os monitores do projeto, ela pode ser substituída para um determinado teste.

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

});

O wrapper do @elastic/synthetics expõe muitos métodos de teste padrão, como as construções before e after, que permitem configurar e desmontar propriedades típicas nos testes, bem como oferecer suporte para muitos métodos auxiliares de asserção comuns. Uma lista completa dos métodos expect compatíveis está listada na documentação. O objeto page do Playwright também é exposto, o que nos permite realizar todas as atividades esperadas fornecidas na API, como a localização dos elementos de página e a simulação de eventos do usuário, como os cliques que são representados no exemplo abaixo.

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 se pode ver no exemplo acima, ele também expõe as construções journey e step. Essa construção espelha a prática de desenvolvimento orientado por comportamento (BDD, pelas iniciais em inglês) de mostrar nos testes a jornada do usuário pela aplicação.

Os desenvolvedores podem realizar os testes em uma aplicação executada localmente como parte do desenvolvimento de recursos para ver as etapas com sucesso e com falha no fluxo de trabalho do usuário. No exemplo abaixo, o comando de inicialização do servidor local é destacado em azul na parte superior. O comando de execução do monitor é apresentado em vermelho mais abaixo.

Como se pode ver pelas marcas verdes ao lado de cada etapa da jornada, obtivemos aprovação em todos os nossos testes. Uhu!

Controlando seus pipelines de CI

É importante usar a execução dos monitores em seu pipeline de CI como uma porta para mesclar alterações de código e carregar a nova versão dos seus monitores. Cada um dos trabalhos no nosso fluxo de trabalho do GitHub Actions será discutido nesta seção e nas próximas.

O trabalho de teste inicia uma instância de teste e executa nossas jornadas do usuário para validar nossas alterações, conforme ilustrado abaixo. Esta etapa deve ser executada para solicitações pull para validar as alterações do desenvolvedor, bem como em push.

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

Observe que, ao contrário da execução da jornada na nossa máquina local, usamos a opção --reporter=junit ao executar npx @elastic/synthetics para fornecer visibilidade das nossas jornadas aprovadas ou, infelizmente, às vezes reprovadas, para o trabalho de CI.

Carregar monitores automaticamente

Para garantir que os monitores mais recentes estejam disponíveis no Elastic Uptime, é recomendável enviar os monitores programaticamente como parte do fluxo de trabalho de CI, como a tarefa de exemplo abaixo faz. Nosso fluxo de trabalho tem um push de um segundo trabalho, mostrado abaixo, que depende da execução bem-sucedida de nosso trabalho test que carrega seus monitores no cluster. Observe que esse trabalho está configurado no nosso fluxo de trabalho para ser executado em push a fim de garantir que as alterações tenham sido validadas em vez de apenas geradas em uma solicitação pull.

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

O assistente @elastic/synthetics init gera um comando push quando você cria seu projeto que pode ser disparado da pasta do projeto. Isso é mostrado abaixo por meio dos steps e da configuração de working_directory. O comando push requer a chave de API do seu cluster da Elastic, que deve ser armazenada como um segredo em um cofre confiável e referenciada por meio de uma variável de ambiente de fluxo de trabalho. Também é vital que os monitores sejam aprovados antes do envio da configuração atualizada do monitor para sua instância do Elastic Synthetics a fim de evitar a interrupção do monitoramento da produção. Ao contrário dos testes e2e executados em um ambiente de teste, os monitores interrompidos afetam as atividades do SRE e, portanto, todas as alterações precisam ser validadas. Por esse motivo, é recomendável aplicar uma dependência à sua etapa de teste por meio da opção needs.

Monitoramento usando o Elastic Synthetics

Após o upload dos monitores, eles fornecem um ponto de verificação regular às equipes de SRE para saber se o fluxo de trabalho do usuário está funcionando conforme o esperado — não apenas porque eles serão executados em uma programação regular, conforme configurado para o projeto e testes individuais, como mostramos anteriormente, mas também devido à capacidade de verificar o estado de todas as execuções do monitor e realizá-las sob demanda.

A guia Monitors Overview (Visão geral dos monitores) nos dá uma visão imediata do status de todos os monitores configurados, bem como a capacidade de executar o monitor manualmente por meio do menu de reticências do cartão.

monitores do elastic observability

Na tela Monitor, também podemos navegar para uma visão geral da execução de um monitor individual para investigar falhas.

detalhes da execução do teste

O outro superpoder de monitoramento que os SREs agora têm é a integração entre esses monitores e ferramentas que os SREs já usam para examinar o desempenho e a disponibilidade das aplicações, como APM, métricas e logs. O menu apropriadamente denominado Investigate (Investigar) permite fácil navegação enquanto os SREs realizam investigações de possíveis falhas ou gargalos.

Também há um equilíbrio entre encontrar problemas e receber notificações sobre possíveis problemas automaticamente. Os SREs já familiarizados com a definição de regras e limites para notificação de problemas ficarão felizes em saber que isso também é possível para monitores de navegador. A edição de uma regra de exemplo é mostrada abaixo.

regras do elastic observability

O status dos monitores de navegador pode ser configurado não apenas para considerar se algum monitor individual ou coletivo se tornou inativo várias vezes, como na verificação de status acima, mas também para avaliar a disponibilidade geral observando a porcentagem de verificações com aprovação dentro de um determinado período. Os SREs não estão apenas interessados em reagir aos problemas de uma maneira tradicional de gerenciamento de produção — eles também querem melhorar a disponibilidade das aplicações.

Gravação dos fluxos de trabalho do usuário

A limitação de gerar testes e2e durante o ciclo de vida do desenvolvimento é que, às vezes, as equipes dão pela falta de algumas coisas e o conjunto de ferramentas anterior era voltado para as equipes de desenvolvimento. Apesar das melhores intenções de projetar um produto intuitivo usando equipes multidisciplinares, os usuários podem usar as aplicações de maneiras não intencionais. Além disso, os monitores escritos pelos desenvolvedores cobrirão apenas os fluxos de trabalho esperados e dispararão o alarme quando esses monitores falharem na produção ou quando começarem a se comportar de maneira diferente se a detecção de anomalia for aplicada a eles.

Quando surgem problemas do usuário, é útil recriar esse problema no mesmo formato dos nossos monitores. Também é importante aproveitar a experiência dos SREs na geração de jornadas do usuário, pois eles considerarão os casos de falha intuitivamente em situações em que os desenvolvedores podem ter dificuldades e se concentrar nos casos bem-sucedidos. No entanto, nem todos os SREs terão experiência ou confiança para escrever essas jornadas usando o Playwright e o @elastic/synthetics.

Video thumbnail

Entra em cena o Elastic Synthetics Recorder! O vídeo acima mostra como ele pode ser usado para registrar as etapas da jornada do usuário e exportá-las para um arquivo JavaScript para inclusão no seu projeto de monitor. Isso é útil para retroalimentar a fase de desenvolvimento e testar correções desenvolvidas para resolver o problema. Essa abordagem não será possível a menos que todos nós unamos nossas forças para usar esses monitores juntos.

Experimente!

A partir da versão 8.8, o @elastic/synthetics e o app Elastic Synthetics estão com disponibilidade geral, e o gravador confiável está na versão beta. Compartilhe suas experiências de união entre as equipes de desenvolvedores e de operações por meio do Synthetic Monitoring na categoria Uptime dos fóruns da comunidade no Discuss ou pelo Slack.

Bom monitoramento!

Publicado originalmente em 6 de fevereiro de 2023; atualizado em 23 de maio de 2023.