npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lcbp/smonitorpkg

v0.2.1

Published

Function package for monitoring VTEX services

Downloads

149

Readme

O Service Monitor Package é um pacote que foi desenvolvido para utilizar em conjunto com o app Service Monitor onde é utilizado no código dos serviços que populam a base de dados de logs para a analise do app.

Pré-requisitos

Para implementar o pacote no código, é necessário primeiro:

Entidade de dados: Ter uma entidade criada no Masterdata conforme foi mostrado na DOC do Service monitor

Serviço da VTEX: É necessário ter um Serviço VTEX criado (ou em construção).

🚀 Instalando

Para instalar o pacote em seu projeto basta executar o seguinte comando:

# Se for NPM
$ npm i @lcbp/smonitorpkg


# Se for Yarn
$ yarn add @lcbp/smonitorpkg

☕ Como utilizar

A biblioteca disponibiliza algumas funções, porém a principal delas é a ServiceMonitorClass que gera uma classe que faz todo o processo de registro dos logs da rota.

ServiceMonitorClass

| Prop | Tipo | Padrão | Descrição | |-------------|----------|--------------|--------------| | routeName | string | - | Nome da rota |

As funções de cada objeto dessa classe são:

startTimer

Inicia o timer de processamento;

getObject

| Prop | Tipo | Padrão | Descrição | |---------------|--------------------------------------------|-----------|--------------------------------------------------------| | isError | boolean | false | Se o log é um erro | | authType | Array<string> | [] | São os metodos de autenticação usados na requisição | | msg | string | Success | Mensagem de retorno da Rota | | returnObject | Record<any, any>, Array<any> ou null | null | Objeto de retorno da requisição | | requestObject | Record<any, any>, Array<any> ou null | null | Objeto enviado para a requisição (body, query ou path) |

Pega o objeto formatado para ser inserido na entidade de dados.

saveData

| Prop | Tipo | Padrão | Descrição | |------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|-----------------------------------------------------------------------------------| | data | type PerformanceObject = { date: string; isError: boolean; msg: string; returnObject: string; requestObject: string; processingTime: number; routeName: RouteName;}; | - | Objeto que será salvo no Master data | | ctx | Context | - | Objeto de contexto do Serviço | | entity | string | - | Entidade padrão onde os logs será registrados | | minLatency | number | 1 | Valor mínimo que a rota demorou para processar para poder registrar no masterdata |

Função que salva o objeto de log dentro do masterdata

getData

| Prop | Tipo | Padrão | Descrição | |------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------|-------------------------------------------------| | data | { data: { startDate: string; endDate: string; pagination?: { page: number; pageSize: number; }; routes: string[]; sort?: string }; ctx: Context; entity: string;} | - | Objeto auxiliar de busca de dados no masterdata | | ctx | Context | - | Objeto de contexto do Serviço | | entity | string | - | Entidade de dados onde os logs estão salvos | | Busca os dados no mastertada | | | |

Como dito acima, essa classe tem como objetivo gerar um objeto de monitoramento na rota, que ao finalizar ou ocorrer um erro no tempo de vida da requisição, ele registra:

  • Nome da rota
  • Data e hora do registro
  • Tempo de processamento em milissegundos
  • Status da requisição se foi de erro ou não
  • O Objeto que foi enviado para a requisição
  • O Objeto de resposta da requisição
  • Mensagem, caso haja

Implementando

Vá até ao controller da sua rota, ou a função onde você deseja registrar o log e que também tenha todos os processos daquela requisição, visto que vamos calcular através dessa classe o tempo de processamento da rota no tempo de vida da requisição.

Primeiro importe o pacote no arquivo do controller

import { ServiceMonitorClass } from '@lcbp/smonitorpkg'

Agora no inicio da função do controller adicione o seguinte código:

const performanceObject = new ServiceMonitorClass({
    routeName: '{{NOME_DA_ROTA}}', // Substitua pelo nome da rota em questão
  })
  performanceObject.startTimer()

Esse processo irá iniciar o objeto de monitoramento, dando um start no "timer" interno.

Agora em cada ponto que finaliza a "jornada" da requisição (como um erro, ou o retorno da requisição) adicione o seguinte código:

ctx.clients.events.sendEvent('', '{{NOME_DO_EVENTO}}',
   performanceObject.getObject({
       isError: false, // Se o retorno é de erro ou não
      
       msg: '', // Mensagem de retorno, caso haja
      
       requestObject: {}, // Objeto que foi enviado pelo usuário no body e caso tenha sido na query monte um objeto com as váriveis enviadas


       returnObject: {}, // Objeto que foi retornado na requisição
   })
)

Como você já deve ter percebido, utilizamos o sendEvents para enviar nosso objeto de monitoramento, mas no próximo passo será explicado como configurar esse evento no seu serviço da VTEX. Pronto agora a sua rota já está pronta para enviar os dados de monitoramento.

Agora vamos criar o evento que salva esses objetos de monitoramento dentro do master data, para isso entre no arquivo node/service.json e adicione esse objeto:

{
  ...
  "events": {
    "savePerformanceLog": {
      "sender": "{{CONTA}}.{{NOME_DO_APP}}",
      "keys": ["send-performance-log"]
    }
  },
}

e substitua as variáveis para o seu cenário, nesse caso o nome do App é o nome do seu app de serviço que está no arquivo ./manifest.json.

Agora crie uma pasta dentro da pasta node do seu serviço com o nome de events e dentro dela crie uma arquivo com o nome savePerformanceLog.ts. Acesse esse arquivo e cole o código abaixo:

import { ServiceMonitorClass } from '@lcbp/smonitorpkg'
import { EventContext, IOClients } from '@vtex/api'


export async function savePerformanceLog(ctx: EventContext<IOClients>) {
  try {
    const performanceObject = new ServiceMonitorClass()


    performanceObject.saveData({
      ctx,
      data: {
        ...ctx.body,
      },
      entity: '{{ENTIDADE_DO_MASTERDATA}}', // Aqui, coloque o acronyum da entidade do masterdata que você criou para registrar os dados dessa API
    })
  } catch (error) {
    console.error(error)
  }

Esse código é responsável por pegar os dados que foram enviados no passo anterior e salvar corretamente na entidade de dados do MasterData.

É possível também criar uma configuração no settingsSchema para deixar essa entidade dinâmica, ou seja, caso seu app seja usado em mais de uma account, você consegue configurar dinamicamente pelas configurações do App para qual entidade os dados serão salvos.

Agora para finalizar acesse o arquivo node/index.ts e adicione a Classe de Serviço o objeto events:

export default new Service({
  clients,
  routes: {
    ...
  },
  events: {
    savePerformanceLog: savePerformanceLog,
  },
})

Isso irá adicionar esse evento ao seu app permitindo escutar o disparo do evento feito no passo anterior.

getErrorMessageInString

| Prop | Tipo | Padrão | Descrição | |-------|----------------------------|--------|-------------------------------------------------------------------------------| | error | (Object, Array ou String) | - | Objeto do erro, o objeto que o catch retorna ou um objeto montado manualmente |

Essa função retornar a mensagem que contém dentro de um objeto de erro, que geralmente segue o seguinte padrão:

  • Se o objeto passado for do tipo string ele retorna ele mesmo
  • error?.message
  • error?.response?.data?.error
  • error?.response?.data?.details
  • E caso não encontre em nenhum dos casos acima retorna por default Unknown error

getObjectInString

| Prop | Tipo | Padrão | Descrição | |-------|---------------------|--------|----------------------------------| | error | (Object ou Array) | - | O objeto que será "stringficado" |

Essa função tenta executar o comando JSON.stringify no objeto, caso não consiga por conta do tamanho do objeto, ele retorna um objeto padrão "stringficado":

{
  "msg": "Unable to get return object",
}

Ícones utilizados

  • Server icons created by RaftelDesign - Flaticon
  • Search icons created by Maxim Basinski Premium - Flaticon alt text
  • Box icons created by Freepik - Flaticon