Gerenciar e monitorar logs é essencial para garantir que aplicativos e serviços estejam operando perfeitamente. Embora o Azure seja uma plataforma poderosa para seus aplicativos, sua configuração pode ser desafiadora e a resolução de bugs usando logs pode ser complicada. Os logs no Azure podem ficar espalhados em vários lugares e vir com alguns problemas: eles podem ser caros para armazenar e não fornecer visibilidade suficiente. 

Neste guia passo a passo, você aprenderá a coletar logs do Azure usando Hubs de Eventos do Azure e Azure Functions. Você enviará esses logs para a New Relic usando nossa Logs API. Ao final deste guia, você terá uma integração de ponta a ponta entre o Azure e o New Relic, assim poderá monitorar seus logs com facilidade e eficácia. 

Pré-requisitos

Do que você precisa para acompanhar este exemplo com êxito? Aqui está uma lista de verificação:

  • Uma conta ativa no Microsoft Azure. Se você não tem uma, pode se cadastrar grátis aqui
  • Uma chave de licença de ingestão do New Relic. Ainda não tem uma conta da New Relic? Cadastre-se para ter uma conta grátis que proporciona acesso total a mais de 30 funcionalidades disponíveis em nossa plataforma e 100 GB de dados por mês gratuitos.

Configuração dos serviços Azure

Vamos começar configurando os nossos serviços Azure e o encaminhamento de logs para a New Relic. Você usará estes três serviços para fazer isso: 

  1. Serviço de Aplicativo para logs de diagnóstico
  2. Hubs de Eventos do Azure
  3. Azure Functions

Neste exemplo, você encaminhará logs para um aplicativo Node hospedado no Serviço de Aplicativo. Por padrão, os logs de diagnóstico para serviços de aplicativo são desabilitados no Azure, então você precisa ativar manualmente os logs de diagnóstico de cada recurso. 

Configuração do serviço

1. Crie um namespace dos Hubs de Eventos do Azure. Acompanhe o guia em vídeo para saber como fazer isso.

2. Após a implantação bem-sucedida do namespace, crie um Hub de Eventos do Azure seguindo as instruções no próximo vídeo.

3. Em seguida, ative as configurações de diagnóstico para seus recursos do Azure. As configurações de diagnóstico permitem especificar quais categorias de logs você quer coletar e para onde enviá-las. Você precisa selecionar os hubs de eventos como o destino dos seus logs e fornecer o nome do namespace e do hub de eventos que criou no passo um. Acompanhe as instruções em vídeo. 

4. Crie chaves de acesso compartilhadas, como demonstrado no vídeo a seguir. Para que o aplicativo Azure Functions se comunique com o hub de eventos para escutar os eventos que chegam, precisamos criar uma chave de acesso compartilhada com somente permissões Listen.

5. Crie um aplicativo Azure Functions. Liste o modo de execução do aplicativo como código e o stack em runtime como Node.js, conforme demonstrado no próximo vídeo. Você pode escolher Windows ou Linux para seus projetos pessoais, mas o stack em runtime para este exemplo deve ser Node.js, pois a lógica de função será escrita em JavaScript.

6. Criar uma nova chave de conexão durante a criação da função pode causar erros. Exemplos incluem a chave de conexão não ser adicionada ao aplicativo de funções durante a criação da função ou uma convenção de nome inválida para o nome da chave de acesso gerada automaticamente, o que pode provocar o mau funcionamento da função.

7. Adicione uma função no contêiner do aplicativo de funções. Selecione o gatilho do Hub de Eventos do Azure como o gatilho e insira o nome do hub de eventos (não é o namespace) que você criou no passo dois. A Conexão do Hub de Eventos deve ser preenchida automaticamente com a chave NRLOGS_EVENTHUB_CONNECTION como uma opção de conexão. Essa é a mesma chave que você acabou de criar no passo anterior. 

Observação: o campo de grupo de consumidores diferencia letras maiúsculas e minúsculas e deve ficar como $Default

Antes de adicionar código à função, crie um nome secreto NR_INGEST_API_KEY para sua chave de licença da New Relic na configuração do aplicativo no nível do aplicativo de funções.

8. Adicione código à função. Quando a função é acionada, o hub de eventos recebe todos os eventos, que são passados adiante como um parâmetro para a função. Copie o trecho abaixo e adicione-o à função criada no passo anterior. 

   const https = require("https");
  
   // Configure the New Relic Log API http options for POST
   const options = {
     hostname: "log-api.newrelic.com",
     port: 443,
     path: "/log/v1",
     method: "POST",
     headers: {
       "Content-Type": "application/json",
       /* ADD YOUR NR INGEST LICENSE TO THE Application Settings of Functions App */
       "Api-Key": process.env.NR_INGEST_API_KEY,
     },
   };
  
   module.exports = function (context, eventHubMessages) {
     const parsedMessages = JSON.parse(eventHubMessages);
  
     try {
       if (parsedMessages.hasOwnProperty("records")) {
         parsedMessages.records.forEach(async (message, index) => {
           /**
           * capture only the console.log() of our app from the message
           * ignoring all other metadata
           */
           let logMessage = JSON.parse(message.resultDescription);
  
           /**
           * Setup the payload for New Relic with decoded message from EventHub
           * with "message", "logtype" as attributes
           */
           let logPayload = {
             message: logMessage,
             logtype: "MSAzure_AppServiceConsoleLogs",
           };
  
           let response = await SendToNR(logPayload);
  
           console.log(
             `Processed message ${message} with response => ${response}`
           );
         });
       }
     } catch (error) {
       console.error(`POST to New Relic Failed ${error}`);
     }
  
     context.done();
   };
  
   function SendToNR(payload) {
     return new Promise((resolve, reject) => {
       const req = https.request(options, (res) => {
         if (res.statusCode < 200 || res.statusCode > 299) {
           return reject(new Error(`HTTP status code ${res.statusCode}`));
         }
  
         const body = [];
         res.on("data", (chunk) => body.push(chunk));
         res.on("end", () => {
           const resString = Buffer.concat(body).toString();
           resolve(resString);
         });
       });
  
       req.on("error", (err) => {
         reject(err);
       });
  
       req.on("timeout", () => {
         req.destroy();
         reject(new Error("Request time out"));
       });
  
       req.write(JSON.stringify(payload));
       req.end();
     });
   }

Observe como você consegue acessar os dados de log por meio do parâmetro de entrada eventHubMessages. eventHubMessages é uma matriz de objetos EventData que têm propriedades como records. Esses registros exibem o conteúdo do log, como EnqueuedTimeUtc, que mostra a hora em que o log foi enviado para o hub de eventos.

Observe também que o código cria uma carga personalizada com um atributo personalizado logType para diferenciar entre as fontes de logs. 

9. Salve e implante a função. Após a implantação da função, espere o aplicativo gerar alguns logs. Para verificar se logs foram criados e encaminhados, observe a interface da New Relic.

10. Verifique se logs aparecem na interface do New Relic. No New Relic, você verá a implementação funcionando e pode explorar os logs encaminhados. Na imagem a seguir, observe como você pode ver a fonte dos logs no atributo logType

Resolução de problemas

Alguns problemas comuns que você pode encontrar durante a configuração dessa solução: 

A função não está sendo executada no gatilho do hub de eventos. Verifique se sua função está configurada adequadamente com a chave de conexão do hub de eventos e se o nome do hub de eventos correto foi fornecido. Verifique e siga as instruções no passo cinco desta publicação. Além disso, garanta que o seu grupo de consumidores está definido como $Default com o uso correto de letras maiúsculas e minúsculas, pois o nome as diferencia. Se você configurou outro grupo de consumidores para seu hub de eventos, garanta que a configuração esteja correta e reveja o passo cinco.

Não consigo ver os logs na New Relic. Em alguns casos, pode demorar alguns minutos até que os dados apareçam. Se você continuar sem ver dados após aguardar, verifique se usou a NR_INGEST_LICENSE correta. 

Resumo

Vamos rever o que você aprendeu nesta publicação, agora que já concluiu o exemplo. 

Primeiro, você ativou a resolução de bugs no Azure usando o recurso de logs de diagnóstico. Isso deu acesso aos logs detalhados do seu aplicativo.

Depois, você configurou o streaming de logs usando os serviços nativos do Azure. Assim que conseguiu transmitir os logs para um local central, ficou mais fácil acessar e analisar os logs em vários recursos do Azure. Esse recurso é útil para aplicativos em larga escala, pois identifica tendências e padrões nos dados.

Por fim, você estabeleceu o encaminhamento de logs para a New Relic por meio dos mesmos serviços nativos. Isso ajuda a analisar os logs em tempo real, fornecendo um tempo de retorno mais rápido para a detecção e correção de problemas no aplicativo.

Os logs de diagnóstico do Azure, o streaming de logs e o encaminhamento de logs para a New Relic podem ser usados em todos os seus aplicativos Azure, sendo uma maneira econômica e eficaz de gerenciar seus logs.