https://a.storyblok.com/f/270183/1368x665/541410e5f5/monitoring-application-health_24.png

Monitoramento do desempenho de aplicativos com Java e a Messages API do Vonage

Publicado em February 21, 2023

Tempo de leitura: 7 minutos

Introdução

A geração e o envio de relatórios de integridade do Actuator são um processo importante que pode ajudar a garantir o bom funcionamento de um aplicativo.

O Spring Boot é um framework popular para a criação de aplicativos Java que oferece um conjunto de ferramentas para monitorar e gerenciar um aplicativo. Um de seus recursos é o Actuator, que fornece um conjunto de endpoints para monitorar o estado de um aplicativo. Esses endpoints podem ser usados para obter informações sobre o desempenho do aplicativo, como uso de memória, uso da CPU e tempos de resposta.

Ao utilizar a Messages API do Vonage, podemos enviar relatórios de integridade do aplicativo por mensagens de texto e, em caso de quaisquer problemas críticos de integridade, podemos enviar mensagens alternativas como um alerta adicional para um número de telefone designado. Neste artigo, discutiremos como instalar e configurar o Spring Boot para gerar relatórios de integridade de uma aplicação e como utilizar as APIs Vonage Voice, SMS e Messages para enviá-los.

Spring Boot

O Spring Boot é um framework baseado em Java utilizado para criar Applications autônomas e prontas para produção, fáceis de desenvolver e executar. Ele é construído com base no Spring Framework e utiliza seus módulos para oferecer uma ampla gama de funcionalidades aos desenvolvedores. Siga este artigo para configurar um projeto no Spring Boot.

Para habilitar o Actuator em sua aplicação Spring Boot, é necessário adicionar a dependência do starter do Spring Boot Actuator ao seu projeto e configurá-la no application.properties arquivo do seu projeto, conforme mostrado abaixo.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Adicione também as seguintes propriedades ao seu arquivo application.properties:

management.endpoints.web.exposure.include=*
management.endpoints.web.base-path=/actuator

Outras dependências são lombok e web. O Actuator oferece um conjunto abrangente de recursos para ajudar você a monitorar e gerenciar sua aplicação Spring Boot, sendo uma ferramenta essencial para qualquer aplicação Spring Boot pronta para produção.

Spring Boot Actuator

O Actuator oferece diversos recursos úteis, tais como:

  • Verificação de integridade: O Actuator oferece um endpoint de verificação de integridade. Esse endpoint retorna um objeto JSON que contém informações sobre a integridade do aplicativo, como se ele está em execução no momento ou indisponível, e se todas as suas dependências estão disponíveis.

  • Métricas: O atuador fornece um endpoint para recuperar métricas, como o número de solicitações, o número de erros e o tempo de resposta.

  • Registros: O atuador fornece um ponto de extremidade para a recuperação de arquivos de log, o que pode ser útil para solucionar problemas.

  • Configuração: O atuador fornece um ponto de acesso para compreender como o aplicativo está configurado e para solucionar problemas.

  • Dump de threads: O Actuator fornece um ponto de contato para a resolução de problemas relacionados a threads.

  • Audit: O Actuator oferece um ponto de extremidade para monitorar as ações dos usuários, como o número de solicitações que eles realizaram.

  • Rastreamento HTTP: O Actuator oferece um endpoint para recuperar um rastreamento de todas as solicitações e respostas HTTP, o que pode ser útil para solucionar problemas relacionados à camada HTTP do aplicativo.

Messages API da Vonage

A Messages API da Vonage é um conjunto de serviços web RESTful que permite aos desenvolvedores enviar e receber mensagens, como SMS e MMS, bem como serviços de mensagens avançadas, como WhatsApp, Viber e Facebook Messenger. A API foi projetada para ser simples de usar e fácil de integrar a outros sistemas e serviços.

Introdução ao Vonage

Para começar a trabalhar com as APIs da Vonage, você precisará se cadastrar para obter um Account na Vonage e, em seguida, criar uma Application nessa Account. À Application serão atribuídas uma chave de API e um segredo, que você utilizará para autenticar suas solicitações à API.

Geração e envio do relatório de integridade das aplicações — A implementação

Para simplificar, vamos monitorar nosso aplicativo em busca de situações em que o lado do servidor gere um código de erro 5xx para as solicitações enviadas a ele. De acordo com o Padrão de Códigos HTTP, 5XX indica um Internal Server Error. Isso significa, essencialmente, que nossa aplicação pode estar enfrentando alguns problemas que exigem atenção. Você pode ampliar essa abordagem para lidar com diferentes códigos de resposta, gerados pela sua aplicação em resposta às solicitações feitas a ela.

Se você quiser salvar as respostas do Actuator, precisará criar um modelo e um repositório para isso. O modelo conterá campos que correspondem aos pares chave-valor da saída JSON do Actuator. Esse assunto não é abordado neste artigo.

Implementação do HttpTraceRepository

Crie uma classe RemoteRepository que implemente a interface “HttpTraceRepository”. A classe utiliza as anotações “Getter” e “Setter” da biblioteca “lombok”, que fornecem métodos getter e setter para os campos da classe sem que o desenvolvedor precise escrevê-los explicitamente.

A classe possui dois métodos que devem ser implementados pela interface HttpTraceRepository: findAll() e add(HttpTrace trace). O método findAll() retorna uma lista vazia de objetos HttpTrace, e o método add(HttpTrace trace) recebe um objeto do tipo HttpTrace. É aqui que entra a sua lógica. Neste caso, ela verifica o código de status da resposta desse objeto trace proveniente de actuator e, se for igual a 500, chama serviços para enviar mensagens SMS por meio da API da Vonage. Você também pode instruí-lo a enviar mensagens pelo WhatsApp.

import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.actuate.trace.http.HttpTrace;
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
import java.util.Collections;
import java.util.List;

@Getter
@Setter
public class RemoteRepository implements HttpTraceRepository {

   @Override
   public List<HttpTrace> findAll() {
       return Collections.emptyList();
   }

   @Override
   public void add(HttpTrace trace) {

       int responseStatusCode = trace.getResponse().getStatus();

       if (responseStatusCode == 500) {
           // call the services to send SMS and Messages via Vonage API
       }
   }
}

O atuador Configuration classe

Em seguida, crie uma classe de configuração para actuator. Essa classe de configuração, ActuatorConfig, configura certos aspectos do recurso Actuator do Spring.

  • @Configuration: Indica que esta classe contém uma ou mais definições @Bean para o Contexto de Aplicação do Spring.

  • @ConditionalOnWebApplication: Essa anotação é um recurso do Spring Boot; ela indica que essa configuração deve ser aplicada somente se a aplicação for uma aplicação web.

  • @ConditionalOnProperty(prefix = "management.trace.http", name = "enabled", matchIfMissing = true): Esta anotação verifica a presença de uma propriedade de configuração específica, neste caso, management.trace.http.enabled, na configuração do aplicativo. Se a propriedade não estiver presente, o valor padrão será true.

  • @EnableConfigurationProperties(HttpTraceProperties.class): Essa anotação instrui o Spring a habilitar o suporte à injeção automática de propriedades de configuração, provenientes dos arquivos de configuração do aplicativo, nas instâncias da classe especificada (HttpTraceProperties)

  • @AutoConfigureBefore(HttpTraceAutoConfiguration.class): Esta anotação indica que a classe ActuatorConfig deve ser processada antes da HttpTraceAutoConfiguration.

A classe também define um método traceRepository() anotado com @Bean e @ConditionalOnMissingBean(HttpTraceRepository.class), o que significa que ele só será executado se nenhum outro bean do tipo HttpTraceRepository tiver sido definido no contexto da aplicação. O método retorna uma nova instância de RemoteRepository que deve ser usada como um HttpTraceRepository.

import org.springframework.boot.actuate.trace.http.HttpTraceRepository;
import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceProperties;
import org.springframework.boot.actuate.autoconfigure.trace.http.HttpTraceAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnWebApplication
@ConditionalOnProperty(prefix = "management.trace.http", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(HttpTraceProperties.class)
@AutoConfigureBefore(HttpTraceAutoConfiguration.class)
public class ActuatorConfig {

	@Bean
	@ConditionalOnMissingBean(HttpTraceRepository.class)
	public RemoteRepository traceRepository() {
    	return new RemoteRepository();
	}
}

Utilidade Service Classes para os serviços da API da Vonage

Para cada um dos serviços da Vonage com os quais se trabalhará, será criada uma service será criada uma classe. Basicamente, uma classe de serviço para cada um dos nossos serviços de mensagens (SMS, WhatsApp, Viber) e uma para o serviço de Voice.

VoiceService classe

Para usar a Voice API da Vonage para enviar uma mensagem de voz, você precisará utilizar o SDK Java da Vonage. É possível enviar mensagens de voz para um número de telefone usando a função de conversão de texto em fala (TTS) ou reproduzindo um arquivo de áudio pré-gravado. Aqui está uma demonstração de como usar o SDK Java da Vonage para enviar uma mensagem de voz:

Primeiro, você precisa adicionar o SDK Java da Vonage como dependência no seu projeto. Para isso, basta adicionar o código a seguir ao seu arquivo pom.xml, caso esteja usando o Maven:

<dependency>
 	<groupId>com.vonage</groupId>
    	<artifactId>client</artifactId>
    	<version>7.1.1</version>
</dependency>

Em seguida, você precisará criar uma nova classe que cuidará do envio da mensagem de voz. Nessa classe, você precisará importar as classes `com.vonage.client.voice.Call` e `com.vonage.client.VonageClient`. Nessa classe, você precisará passar seu ID de aplicativo e sua chave privada para autenticar seu aplicativo durante as chamadas.

String applicationId = "your-application-id";
String privateKeyPath = "path/to/private.key";

Em seguida, crie uma nova instância da VonageClient classe e forneça seu ID de aplicação e o caminho para sua chave privada.

VonageClient client = VonageClient
.builder()
.applicationId(applicationId)
.privateKeyPath(privateKey)
.build();

Agora, você pode criar uma nova instância da classe Call e definir as propriedades from, to e answer_url. A from propriedade “from” é o número de telefone ou número virtual de onde você está enviando a mensagem; a to propriedade “to” é o número para o qual você está enviando a mensagem, e a answer_url propriedade é a URL que será solicitada quando a chamada for atendida.

Call call = new Call();
call.setFrom(FROM_NUMBER);
call.setTo(TO_NUMBER);
call.setAnswerUrl(ANSWER_URL);

Para simplificar, crie uma classe VonageClientProvider na qual você crie uma instância do seu cliente Vonage — com suas credenciais. Isso é essencial para que você não precise repetir o código em outras classes.

import com.vonage.client.VonageClient;

public class VonageClientProvider {

    private static final String APPLICATION_ID = "VONAGE_APPLICATION_ID";
    private static final String PRIVATE_KEY = "VONAGE_PRIVATE_KEY_PATH";
    private static VonageClient instance;

    private VonageClientProvider() {}

    public static VonageClient getInstance() {
        if (instance == null) {
            instance = VonageClient.builder()
                    .applicationId(APPLICATION_ID)
                    .privateKeyPath(PRIVATE_KEY)
                    .build();
        }

        return instance;
    }
}

messagesService classe

Aqui está uma classe em Java que demonstra como enviar um SMS, uma mensagem pelo WhatsApp e uma mensagem pelo Viber usando a Messages API do Vonage:

import com.vonage.client.VonageClient;
import com.vonage.client.messages.MessageResponse;
import com.vonage.client.messages.MessagesClient;
import com.vonage.client.messages.sms.SmsTextRequest;
import com.vonage.client.messages.viber.Category;
import com.vonage.client.messages.viber.ViberTextRequest;
import com.vonage.client.messages.whatsapp.WhatsappTextRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class MessagingService {

    private static final String VONAGE_NUMBER = "YOUR_VONAGE_NUMBER_HERE";

    public static void sendSms(String toNumber, String text) {

        VonageClient client = VonageClientProvider.getInstance();

        MessagesClient smsClient = client.getMessagesClient();

        var message = SmsTextRequest.builder()
                .from(VONAGE_NUMBER).to(toNumber)
                .text(text)
                .build();


            MessageResponse response = smsClient.sendMessage(message);
            log.info("Message sent successfully. ID: "+response.getMessageUuid());

    }

    public static void sendWhatsApp(String toNumber, String text) {

        VonageClient client = VonageClientProvider.getInstance();

        MessagesClient whatsAppClient = client.getMessagesClient();

        var message = WhatsappTextRequest.builder()
                .from(VONAGE_NUMBER).to(toNumber)
                .text(text)
                .build();

            MessageResponse response = whatsAppClient.sendMessage(message);
            log.info("Message sent successfully. ID: "+response.getMessageUuid());
    }

sendViber() método

public static void sendViber(String toNumber, String text) {

        VonageClient client = VonageClientProvider.getInstance();

        MessagesClient viberClient = client.getMessagesClient();

        var message = ViberTextRequest.builder()
                .from(VONAGE_NUMBER).to(toNumber)
                .text(text)
                .category(Category.TRANSACTION)
                .build();

            MessageResponse response = viberClient.sendMessage(message);
            log.info("Message sent successfully. ID: " + response.getMessageUuid());
    }

Melhorando RemoteRepository classe

Todos os serviços necessários para o envio de mensagens por meio da API da Vonage já foram criados. Acesse a RemoteRepository classe e configure o autowire para cada um desses serviços, de modo que, quando um “500 - Erro interno do servidor” for gerado, cada um deles seja chamado e executado na ordem e no formato que você desejar. A estrutura completa da RemoteRepository classe é mostrada abaixo:

import com.vonage.tracer.service.MessagingService;
import com.vonage.tracer.service.VoiceService;
import lombok.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.trace.http.HttpTrace;
import org.springframework.boot.actuate.trace.http.HttpTraceRepository;

import java.util.Collections;
import java.util.List;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class RemoteRepository implements HttpTraceRepository {
    @Autowired
    private MessagingService messagingService;

    @Autowired
    private VoiceService voiceService;

    @Override
    public List<HttpTrace> findAll() {
        return Collections.emptyList();
    }

    @SneakyThrows
    @Override
    public void add(HttpTrace trace) {

        int responseStatusCode = trace.getResponse().getStatus();
        String errorMessage = "Check Server - 500 generated. Kindly check the server for an Internal Server Error";

        if (responseStatusCode == 500) {

            // call the services to send SMS, Messaging and Voice Messages via Vonage API

            MessagingService.sendSms(
                    "<sender-number-here",
                    "<recipient-number-here"
            );

            MessagingService.sendWhatsApp(
                    "<recipient-number-here", errorMessage
                    );

            MessagingService.sendViber(
                    "<recipient-number-here", errorMessage);

            voiceService.sendVoiceMessage(
                    "<recipient-here", errorMessage);

        }
    }
}

Agora você pode criar seus controladores e, sempre que for feita uma chamada à sua aplicação e ela resultar em um código de resposta 500, os serviços serão chamados um após o outro. Você tem total liberdade para controlar como isso funciona, mas isso já deve ser o suficiente para você dar os primeiros passos rumo a grandes conquistas.

Conclusão

Neste artigo, vimos como gerar e enviar mensagens para os respectivos endereços ou locais quando ocorre um erro HTTP 500 em nosso servidor. Com isso, você pode verificar o conteúdo do objeto de rastreamento do Actuator e descobrir o que mais é possível fazer com ele. Você também pode fazer muito mais com a API da Vonage. Confira a documentação aqui. O código deste artigo pode ser encontrado aqui também.

Venha participar da conversa no Slack da Comunidade Vonage ou envie uma mensagem no Twitter.

Compartilhar:

https://a.storyblok.com/f/270183/400x398/eaee70de70/tolulope-ayemobola.png
Tolulope AyemobolaAutor convidado

Tolulope é um engenheiro de software em ascensão que adora programar e escrever sobre o que faz. Quando não está programando, ele aproveita seu tempo como DJ.