Execução do RUM com o Elastic APM | Elastic Blog
Engineering

Degustação do RUM da Elastic

Desculpe se eu o enganei e o fiz pensar que você degustaria um maravilhoso coquetel feito de rum e você percebeu que o RUM de que estou falando não é o rum que você imaginava. Mas tenha a certeza de que o Elastic RUM é igualmente maravilhoso! Vamos degustar! Eu não quero assustá-lo, mas levará um pouco de tempo para você assimilar os detalhes que tratarei neste blog.

O que é o RUM?

O Elastic RUM (Monitoramento real de usuário) captura as interações dos usuários com o navegador da web e fornece uma visualização detalhada da “experiência real do usuário” dos seus aplicativos web do ponto de vista do desempenho. O Agente RUM da Elastic é um Agente JavaScript, ou seja, ele oferece suporte a qualquer aplicativo baseado em JavaScript. O RUM pode fornecer informações valiosas de seus aplicativos. Alguns dos benefícios comuns do RUM são estes:

  • Os dados de desempenho RUM podem ajudá-lo a identificar gargalos e descobrir como os problemas de desempenho de sites afetam a experiência dos seus visitantes.
  • As informações de agente de usuário capturadas pelo RUM permitem identificar os navegadores, os dispositivos e as plataformas mais usados pelos clientes para você poder fazer otimizações fundamentadas em seu aplicativo.
  • Juntamente com as informações de localização, os dados de desempenho de usuário individual do RUM ajudam a entender o desempenho regional do seu site em nível mundial.
  • O RUM fornece informações e medidas para os SLAs (Acordos de nível de serviço) dos seus aplicativos.

Introdução ao RUM usando o Elastic APM

Neste blog, vou orientá-lo passo a passo por todo o processo de instrumentar um único aplicativo Web simples criado com um frontend React e um backend Spring Boot. Você verá como é fácil usar o agente RUM. Como bônus, você também verá como o Elastic APM vincula as informações de desempenho do frontend e do backend a uma visão de rastreamento holística e distribuída. Veja meu blog anterior para obter uma visão geral do Elastic APM e do rastreamento distribuído se tiver interesse em saber mais detalhes.

Para usar o RUM do Elastic APM, você precisa ter o Elastic Stack com o servidor APM instalado. Evidentemente você pode fazer download e instalar o mais recente Elastic Stack com servidor APM localmente no computador. Entretanto, a abordagem mais fácil seria criar uma conta de avaliação do Elastic Cloud e ter o cluster pronto em alguns minutos. O APM está habilitado para o modelo otimizado de E/S padrão. De agora em diante, vou pressupor que você tem um cluster já pronto.

Amostra do aplicativo

O aplicativo que vamos instrumentar é um simples aplicativo de banco de dados de carros criado com um frontend React e um backend Spring Boot que oferece acesso de API a um banco de dados de carros interno da memória. O aplicativo é propositadamente simples. A ideia é mostrar as etapas de instrumentação detalhadas a partir do zero para você poder instrumentar os próprios aplicativos seguindo as mesmas etapas.

Um aplicativo simples com um frontend React e um backend Spring

Crie um diretório chamado CarApp em qualquer local no notebook. Faça clonagem do aplicativo de frontend e de backend nesse diretório.

git clone https://github.com/adamquan/carfront.git
git clone https://github.com/adamquan/cardatabase.git

Como você pode ver, o aplicativo é extremamente simples. Há somente alguns componentes no frontend React e algumas classes no aplicativo Spring Boot de backend. Desenvolva e execute o aplicativo seguindo as instruções em GitHub tanto para o frontend quanto para o backend. Você deverá ver algo assim: Você pode navegar, filtrar carros e executar opções de CRUD neles.

A interface de usuário simples do React

Agora, com o aplicativo em execução, estamos prontos para passar pela instrumentação usando o agente RUM.

Instrumentação pronta avançada com o RUM

Vamos primeiro instalar e configurar o agente RUM. Existem duas maneiras de fazer isso:

  1. Para aplicativos do lado do servidor, você pode instalar o agente RUM como uma dependência e inicializá-lo.

    npm install @elastic/apm-rum --save
        
  2. Instale o agente RUM com a configuração HTML.

    <script src="https://unpkg.com/@elastic/apm-rum@4.0.1/dist/bundles/elastic-apm-rum.umd.min.js">
    </script>
    <script>
      elasticApm.init({
        serviceName: 'carfront',
        serverUrl: 'http://localhost:8200',
        serviceVersion: '0.90'
      })
    </script>
        

Como o nosso frontend é um aplicativo React, vamos usar a primeira abordagem. Sob o mesmo diretório do seu index.js, há um arquivo chamado rum.js que contém o seguinte código:

import { init as initApm } from '@elastic/apm-rum'
var apm = initApm({
 // Definir nome de serviço obrigatório (caracteres permitidos: a-z, A-Z, 0-9, -, _ e espaço)
 serviceName: 'carfront',
 // Definir a versão do seu aplicativo
 // Usado no Servidor APM para localizar o mapa de origem correto
 serviceVersion: '0.90',
 // Definir URL do Servidor APM personalizado (padrão: http://localhost:8200)
 serverUrl: 'https://aba7c3d90b0b4820b05b0a9df44c096d.apm.us-central1.gcp.cloud.es.io:443',
 // distributedTracingOrigins: ['http://localhost:8080'],
})
export default apm;

É só fazer isso para inicializar o agente RUM! A seguir está uma breve explicação de algumas das configurações:

  1. Service name: O nome do serviço precisa ser definido. Ele representa seu aplicativo na IU do APM. Atribua um nome significativo.
  2. Service version: Esta é a versão do seu aplicativo. Este número de versão também é usado pelo servidor APM para localizar o mapa de origem correto. Vamos tratar do mapa de origem em detalhes posteriormente.
  3. Server URL: Esta é a URL do servidor APM. Observe que a URL do servidor APM normalmente é acessível pela Internet pública, porque o seu agente RUM relata dados para ele a partir dos navegadores de usuário final na Internet.
  4. Vamos tratar de distributedTracingOrigins posteriormente.

Quem tem familiaridade com os agentes de backend do Elastic APM pode estar imaginando por que o token do APM não foi informado aqui. Isso ocorre porque o agente RUM na verdade não usa um token do APM secreto. O token só é usado para agentes de backend. Como o código de frontend é público, o token secreto não oferece segurança adicional.

Vamos carregar este arquivo JavaScript quando o aplicativo for carregado e incluí-lo nos locais onde queremos fazer instrumentação personalizada. Por enquanto, vamos ver o que obtemos de imediato, sem qualquer instrumentação personalizada. Para fazer isso, bastará incluirmos rum.js em index.js. O arquivo index.js importa rum.js e define um nome de carregamento de página. Sem definir um nome de carregamento de página, você verá o carregamento da página listado como “Unknown” (Desconhecido) na IU do APM, o que não é muito intuitivo. A seguir está a aparência de index.js.

import apm from './rum'
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
apm.setInitialPageLoadName("Car List")
ReactDOM.render(<App />, document.getElementById('root'));
serviceWorker.unregister();

Gere um pouco de tráfego para seu aplicativo. Faça login no Kibana e clique na IU do APM. Você deverá ver um serviço chamado “carfront” (dianteira do carro) listado. Se você clicar no nome do serviço, acessará a página de transação. Você deverá ver a lista de “page-load” (carregamento de página) padrão e ver um carregamento de página “car list” (lista de carros). Se não vir essa lista, verifique se selecionou o intervalo de tempo como “Last 15 minutes” (Últimos 15 minutos) no seletor de tempo. Clique no link “car list”, e você verá uma visualização em cascata de interações de navegador como esta:

Uma amostra de transação no Elastic APM

Está surpreso com a quantidade de informações capturadas pelo agente RUM por padrão? Preste atenção redobrada aos marcadores como timeToFirstByte, domInteractive, domComplete e firstContentfulPaint. Passe o mouse sobre os pontos pretos para ver os nomes. Eles dão excelentes detalhes sobre recuperação de conteúdo e renderização de navegador desse conteúdo. Preste atenção também a todos os dados de desempenho sobre o carregamento de recursos do navegador. Com a simples inicialização do agente RUM, sem qualquer instrumentação personalizada, você obtém imediatamente todas essas métricas de desempenho detalhadas! Quando houver um problema de desempenho, essas métricas permitirão decidir facilmente se o problema é devido à lentidão nos serviços de backend, na rede ou simplesmente no navegador cliente. Isso é muito impressionante!

Para aqueles que precisam recapitular o conteúdo, a seguir está uma breve explicação das métricas de desempenho da Web. É muito importante lembrar que, para estruturas de aplicativos Web modernas como o React, essas métricas podem representar somente a parte “estática” da página da Web, devido à natureza assíncrona do React. Por exemplo, o conteúdo dinâmico ainda pode estar sendo carregado depois de domInteractive, como você verá mais adiante.

  • timeToFirstByte é a quantidade de tempo que um navegador espera para receber a primeira informação do servidor Web depois de solicitá-la. Ele representa uma combinação da velocidade de processamento do lado do servidor e da rede.
  • domInteractive é o tempo imediatamente anterior ao momento em que o agente de usuário define como “interactive” (interativa) a prontidão do documento atual, o que significa que o navegador concluiu a análise de todo o HTML e a construção DOM.
  • domComplete é o tempo imediatamente anterior ao momento em que o agente de usuário define como “complete” (concluída) a prontidão do documento atual, o que significa que a página e todos os seus sub-recursos, como as imagens, tiveram o download concluído e estão prontos. O spinner de carregamento parou de girar.
  • firstContentfulPaint é o tempo em que o navegador renderiza a primeira parte do conteúdo do DOM. Esse é um marco importante para os usuários porque fornece comentários de que a página realmente está sendo carregada.

Instrumentação personalizada flexível

O agente RUM proporciona imediatamente instrumentação detalhada para a interação do navegador, como você acabou de ver. Você também poderá fazer instrumentações personalizadas quando for necessário. Por exemplo, como o aplicativo React é um aplicativo de página única e a exclusão de um carro não disparará um “page load”, o RUM por padrão não captura os dados de desempenho da exclusão de um carro. Podemos usar transações personalizadas para uma situação como essa.

Com a nossa versão atual (APM Real User Monitoring JavaScript Agent 4.x), os usuários precisam criar manualmente transações para chamadas AJAX e chamadas SPA (Aplicativo de página única) que não disparam um carregamento de página. Em algumas estruturas, como JSF, há muito pouco controle sobre o JavaScript. Assim, não é viável criar manualmente transações para cliques de botão que iniciam solicitações AJAX. Mesmo se o desenvolvedor tiver controle direto sobre as solicitações AJAX, a instrumentação de um aplicativo grande exigirá enormes esforços. Estamos planejando aprimorar o agente RUM para que ele crie automaticamente uma transação para essas solicitações caso não haja uma ativa no momento. Isso faria com que a autoinstrumentação cobrisse uma parte muito maior do aplicativo sem que os desenvolvedores precisassem adicionar via programação a lógica de rastreamento a seus aplicativos.

O botão "New Car" (Novo carro) em nosso aplicativo de frontend permite adicionar um novo carro ao banco de dados. Vamos instrumentar o código para capturar o desempenho de adição de um novo carro. Abra o arquivo Carlist.js no diretório de componentes. Você verá o código a seguir:

// Adicionar novo carro
addCar(car) {
    // Criar transação personalizada
    var transaction = apm.startTransaction("Add Car", "Car");
    apm.addTags(car);
    fetch(SERVER_URL + 'api/cars',
        {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(car)
        })
        .then(res => this.fetchCars())
        .catch(err => console.error(err))
}
fetchCars = () => {
    fetch(SERVER_URL + 'api/cars')
        .then((response) => response.json())
        .then((responseData) => {
            this.setState({
                cars: responseData._embedded.cars,
            });
        })
        .catch(err => console.error(err));
        // Encerrar a transação atual ao final da chamada de retorno de resposta
        var transaction = apm.getCurrentTransaction()
        if (transaction) transaction.end()
}

O código criou uma nova transação chamada “Add Car” (Adicionar carro) de tipo “Car” (Carro). Assim, ele marcou a transação com o carro para fornecer informações contextuais. A transação foi encerrada ao final da chamada de retorno de resposta.

Adicione um novo carro da IU Web do aplicativo. Clique na IU do APM no Kibana. Você deverá ver uma transação “Add Car” listada. Verifique se selecionou “Car” (Carro) no menu suspenso “Filter by type” (Filtrar por tipo). Por padrão, ele exibe transações “page-load” (carregamento de página).

Filtragem por tipo no Elastic APM

Clique no link de transação “Add Car”. Você deverá ver informações de desempenho da transação personalizada “Add Car”:

Amostra de transação no Elastic APM filtrada por tipo de 'car'

Clique na guia “Tags” (Marcas). Você verá as marcas que adicionamos. Marcas e logs adicionam informações contextuais valiosas aos rastreamentos do APM.

Análise por marca de tipo no Elastic APM

Isso realmente é tudo o que precisamos para fazer uma instrumentação personalizada — um processo simples, e mesmo assim eficaz! Para obter mais detalhes, consulte a documentação da API.

Visualizações personalizadas avançadas do APM com o Kibana

O Elastic APM oferece uma IU do APM selecionada e painéis internos do APM para visualizar todos os dados do APM capturados imediatamente pelos agentes. Você também pode criar suas próprias visualizações personalizadas. Por exemplo, os dados de agente de usuário e de IP de usuário capturados pelo agente RUM representam informações muito ricas sobre seus clientes. Com todas as informações de agente de usuário e de IP de usuário, é possível criar uma visualização como esta para mostrar a origem do tráfego da Web em um mapa e quais sistemas operacionais e navegadores seus clientes estão usando. Você pode usar pipelines de nó de ingestão para enriquecer e transformar os dados do APM. Todas essas informações permitem otimizar seu aplicativo com mais inteligência.

Visualização dos dados do Elastic APM em um painel do Kibana

Veja o panorama geral com rastreamento distribuído

Como bônus, também vamos instrumentar nosso aplicativo Spring Boot de backend para que você tenha uma única visualização completa da transação geral do navegador da Web até o banco de dados de backend. O rastreamento distribuído do Elastic APM permite fazer isso.

Configuração do rastreamento distribuído nos agentes do RUM

O rastreamento distribuído é habilitado por padrão no agente RUM. Entretanto, ele inclui somente solicitações feitas na mesma origem. Para incluir solicitações de origem cruzada, você precisa definir a opção de configuração distributedTracingOrigins. Você também terá de definir a política CORS no aplicativo de backend, como falaremos na próxima seção.

Para o nosso aplicativo, o frontend é servido a partir de http://localhost:3000. Para incluir solicitações feitas a http://localhost:8080, precisamos adicionar a configuração distributedTracingOrigins ao nosso aplicativo React. Isso é feito em rum.js. O código já está lá. Basta retornar ao código-fonte o comentário da linha.

var apm = initApm({
  ...
  distributedTracingOrigins: ['http://localhost:8080']
})

Isso informa com eficácia ao agente para que adicione o cabeçalho HTTP de rastreamento distribuído (elastic-apm-traceparent) às solicitações feitas a http://localhost:8080.

Para usar a instrumentação padrão imediatamente no lado do servidor, você precisa fazer download do agente Java e começar o seu aplicativo com ele. A seguir está o método que usei para configurar meu projeto Eclipse para executar o aplicativo Spring Boot de backend. Você precisará configurar isso usando sua própria URL do APM e token do APM.

-javaagent:/Users/aquan/Downloads/elastic-apm-agent-1.4.0.jar 
-Delastic.apm.service_name=cardatabase 
-Delastic.apm.application_packages=com.packt.cardatabase
-Delastic.apm.server_urls=https://aba7c3d90b0b4820b05b0a9df44c096d.apm.us-central1.gcp.cloud.es.io:443 
-Delastic.apm.secret_token=jeUWQhFtU9e5Jv836F

Configuração do Eclipse para enviar dados de backend ao Elastic APM

Agora, atualize a lista de carros do navegador para gerar outra solicitação. Vá até a IU do APM do Kibana e marque o carregamento de página “car list” (lista de carros). Você deverá ver algo como a captura de tela a seguir. Como você pode ver, os dados de desempenho do lado do cliente provenientes do navegador e os dados de desempenho do lado do servidor, incluindo acesso JDBC, aparecem perfeitamente em um rastreamento distribuído! Observe diferentes cores para diferentes partes do rastreamento distribuído. Lembre-se de que esse é o rastreamento padrão obtido, sem precisar fazer qualquer instrumentação personalizada do lado do servidor, bastando apenas iniciar o aplicativo com o agente. Sinta o poder do Elastic APM e do rastreamento distribuído!

Rastreamento distribuído (backend e frontend) no Elastic APM

Para leitores que realmente estejam prestando atenção à visualização de linha do tempo anterior, você pode estar imaginando por que a transação de carregamento de página “Car List” (Lista de carros) se encerra em 193 ms, que é o tempo domInteractive, enquanto os dados ainda estão sendo servidos do backend. Essa é uma excelente pergunta! Isso se deve ao fato de que as chamadas de busca são assíncronas por padrão. O navegador “acha” que concluiu a análise de todo o HTML e a construção DOM em 193 ms porque ele carregou todo o conteúdo HTML “estático” proveniente do servidor Web. Em contrapartida, o React ainda está carregando os dados do servidor de backend de forma assíncrona.

CORS (Compartilhamento de recursos de origem cruzada)

O agente RUM é somente uma parte do quebra-cabeças em um rastreamento distribuído. Para usar o rastreamento distribuído, precisamos configurar adequadamente outros componentes também. Um dos componentes que normalmente você precisará configurar é o compartilhamento de recursos de origem cruzada, vulgo CORS! Isso porque os serviços de frontend e backend geralmente são implantados em separado. Com a política de mesma origem, suas solicitações de frontend de uma origem diferente até o backend falharão sem o CORS devidamente configurado. Basicamente, o CORS é uma maneira de o lado do servidor verificar se as solicitações provenientes de uma origem diferente são permitidas. Para ler mais sobre as solicitações de origem cruzada e por que esse processo é necessário, veja a página da MDN sobre CORS (Compartilhamento de recursos de origem cruzada).

O que isso significa para nós? Duas coisas:

  1. Que devemos definir a opção de configuração distributedTracingOrigins, como fizemos.
  2. Que, com essa configuração, o agente RUM também envia uma solicitação HTTP OPTIONS antes da solicitação HTTP real para verificar se todos os cabeçalhos e métodos HTTP têm suporte e se a origem é permitida. Especificamente, http://localhost:8080 receberá uma solicitação OPTIONS com os cabeçalhos a seguir:

    Access-Control-Request-Headers: elastic-apm-traceparent
    Access-Control-Request-Method: [request-method]
    Origin: [request-origin]
        
    E o servidor do APM deverá responder a ele com estes cabeçalhos e um código de status 200:

    Access-Control-Allow-Headers: elastic-apm-traceparent
    Access-Control-Allow-Methods: [allowed-methods]
    Access-Control-Allow-Origin: [request-origin]
        

A classe MyCorsConfiguration em nosso aplicativo Spring Boot faz exatamente isso. Há diferentes maneiras de configurar o Spring Boot para fazer isso, mas aqui estamos usando uma abordagem baseada em filtros. Ou seja, configurar nosso aplicativo Spring Boot do lado do servidor para permitir solicitações de qualquer origem com quaisquer cabeçalhos HTTP e quaisquer métodos HTTP. Talvez você não queira ser tão aberto com seus aplicativos de produção.

@Configuration
public class MyCorsConfiguration {
    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<CorsFilter>(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }
}

Vamos concluir o blog com mais um recurso avançado do agente RUM: mapas de origem. Os mapas de origem facilitam muito a depuração dos erros com seu aplicativo informando exatamente onde ocorreu o erro no código fonte original, em vez do código minificado criptografado.

Fácil depuração com mapas de origem

É prática comum minificar pacotes de JavaScript para implantação de produção por questões de desempenho. Entretanto, a depuração de código minificado é inerentemente difícil. A captura de tela a seguir mostra uma mensagem de erro capturada pelo agente RUM para um build de produção. Como você pode ver, o rastreamento do stack de exceção não faz muito sentido porque trata-se de código minificado. Todas as linhas de erro mostram arquivos javascript como 2.5e9f7401.chunk.js, e sempre apontam para “line 1” devido ao modo como a minificação foi feita. Não seria uma maravilha se fosse possível ver exatamente o código fonte do jeito que foi desenvolvido aqui?

O código minificado no Elastic APM pode ser resolvido com um mapa de recursos

Os mapas de origem são úteis. Você pode gerar mapas de origem para os pacotes e fazer upload deles para o servidor do APM. O servidor do APM poderá converter os erros do código minimizado para o código fonte original e apresentar uma mensagem de erro bem mais inteligível.

Vamos ver como podemos fazer isso para o nosso aplicativo React de frontend. Vamos desenvolver um build de produção para o nosso aplicativo e fazer upload dos mapas de origem. Você pode criar um build de produção usando o comando a seguir:

npm run build

Você deverá ver a mensagem a seguir ao final do build:

The build folder is ready to be deployed.
You may serve it with a static server:
  serve -s build

Você pode ler mais detalhes sobre o build de produção aqui: https://facebook.github.io/create-react-app/docs/production-build

Verifique se já empregou os comandos install serve:

npm install -g serve

Coloque o aplicativo React em modo de produção com este comando:

serve -s build

Quando o aplicativo React estiver em modo de produção, o ícone de React Developer Tools for Chrome terá um plano de fundo escuro. Quando o aplicativo React estiver em modo de desenvolvimento, o ícone terá um plano de fundo vermelho. Verifique se você está executando o build de produção.

Agora, se clicar no botão de erro para gerar um erro e conferi-lo na IU do APM do Kibana, você verá o stack de erro minificado como a captura de tela anterior.

Vamos carregar nossos mapas de origem e ver a mágica acontecer! Os mapas de origem são gerados sob o diretório $APP-PATH/carfront/build/static/js. Entre nele e você verá três arquivos de mapa de origem para os três arquivos JavaScript. Execute o seguinte comando para fazer upload deles para o servidor APM. Verifique se alterou a URL, o nome do arquivo e outros parâmetros para que correspondam à versão, ao build e ao ambiente do aplicativo. Também verifique se usou o token de autorização do servidor APM.

curl https://aba7c3d90b0b4820b05b0a9df44c096d.apm.us-central1.gcp.cloud.es.io:443/v1/rum/sourcemaps -X POST \
  -F sourcemap="@./main.b81677b7.chunk.js.map" \
  -F service_version="0.90" \
  -F bundle_filepath="http://localhost:5000/static/js/main.b81677b7.chunk.js" \
  -F service_name="carfront" \
  -H "Authorization: Bearer jeUWQhFtU9e5Jv836F"
curl https://aba7c3d90b0b4820b05b0a9df44c096d.apm.us-central1.gcp.cloud.es.io:443/v1/rum/sourcemaps -X POST \
  -F sourcemap="@./runtime~main.fdfcfda2.js.map" \
  -F service_version="0.90" \
  -F bundle_filepath="http://localhost:5000/static/js/runtime~main.fdfcfda2.js" \
  -F service_name="carfront" \
  -H "Authorization: Bearer jeUWQhFtU9e5Jv836F"
curl https://aba7c3d90b0b4820b05b0a9df44c096d.apm.us-central1.gcp.cloud.es.io:443/v1/rum/sourcemaps -X POST \
  -F sourcemap="@./2.5e9f7401.chunk.js.map" \
  -F service_version="0.90" \
  -F bundle_filepath="http://localhost:5000/static/js/2.5e9f7401.chunk.js" \
  -F service_name="carfront" \
  -H "Authorization: Bearer jeUWQhFtU9e5Jv836F"

Preste atenção redobrada se a versão do serviço for uma sequência de caracteres e se ela corresponder exatamente à versão do serviço que você configurou no aplicativo React. Nesse caso, estamos fazendo upload com service_version="0.90", e a versão do serviço está definida como "0.90" no aplicativo. Se você carregar os mapas de origem com service_version="0.9" (sem o 0 à direita), ele não funcionará!

Depois que o mapa de serviço for carregado no servidor APM, você poderá localizar todos os mapas de origem com essa solicitação no Dev Tools (sua versão pode ser diferente):

GET apm-6.6.1-sourcemap/_search

Gere outro erro e confira o rastreamento de stack novamente na guia de erro da IU do APM. Você verá o rastreamento de stack como a captura de tela a seguir, refletindo perfeitamente o código fonte original! Agora está bem mais fácil depurar e identificar problemas!

Após a implementação de um mapa de origem, o código real agora está visível no Elastic APM

Resumo

Espero que este blog tenha esclarecido que a instrumentação dos aplicativos com o Elastic RUM é simples e fácil, e mesmo assim extremamente eficaz. Junto com outros agentes APM para serviços de backend, o RUM proporciona uma visão holística do desempenho dos aplicativos de um ponto de vista do usuário final por meio do rastreamento distribuído.

Volto a lembrar que, para começar com o Elastic APM, você pode fazer download do servidor Elastic APM para executá-lo localmente ou criar uma conta de avaliação do Elastic Cloud e ter um cluster pronto em alguns minutos.

Como sempre, acesse o fórum do Elastic APM se quiser abrir uma discussão ou tiver dúvidas. Deguste o RUM sem moderação!