Pular para conteúdo

METRIC - Rastrear Métricas e KPIs

O que é este Node?

O METRIC é o node responsável por rastrear métricas customizadas e KPIs (Key Performance Indicators) com valores numéricos, unidades e dimensões para monitoramento de performance.

Por que este Node existe?

Medir performance é essencial para otimização. O METRIC existe para:

  1. KPIs de negócio: Medir indicadores chave (receita, conversão, churn)
  2. Performance técnica: Rastrear latência, throughput, taxa de erro
  3. Monitoramento: Acompanhar saúde do sistema em tempo real
  4. Alertas: Detectar anomalias e acionar alertas automaticamente
  5. Dashboards: Alimentar painéis de visualização de métricas

Como funciona internamente?

Quando o METRIC é executado, o sistema:

  1. Valida dados obrigatórios (name e value)
  2. Converte value para número se necessário
  3. Define tipo da métrica (gauge, counter, histogram, timer)
  4. Adiciona dimensões para segmentação
  5. Adiciona contexto automático (flowId, userId, sessionId)
  6. Armazena métrica no sistema de métricas
  7. Retorna confirmação com dados da métrica registrada

Código interno (analytics-executor.service.ts:125-157):

private async executeMetric(parameters: any, context: any): Promise<any> {
  const { name, value, unit, type, dimensions, timestamp } = parameters;

  this.logger.log(`📈 METRIC - ${name}: ${value} ${unit || ''}`);

  if (!name || value === undefined || value === null) {
    throw new Error('Metric name and value are required');
  }

  const metric = {
    name: name,
    value: Number(value),
    unit: unit || 'count',
    type: type || 'gauge', // gauge, counter, histogram, timer
    dimensions: dimensions || {},
    timestamp: timestamp || new Date().toISOString(),
    context: {
      flowId: context.flowId,
      userId: context.userId,
      sessionId: context.sessionId
    }
  };

  // Store metric (in production, send to metrics service like CloudWatch, Datadog, etc.)
  await this.storeMetric(metric);

  return {
    success: true,
    action: 'metric_recorded',
    metric: metric,
    timestamp: metric.timestamp
  };
}

Quando você DEVE usar este Node?

Use METRIC sempre que precisar medir valores numéricos:

Casos de uso:

  1. Performance de flow: Medir tempo de execução, taxa de conclusão
  2. Métricas de negócio: Valor médio de pedidos, taxa de conversão
  3. Infraestrutura: CPU, memória, latência de APIs
  4. Qualidade: Taxa de erro, tempo de resposta, disponibilidade
  5. Produto: Usuários ativos, features mais usadas, retenção
  6. Financeiro: Receita, ticket médio, churn, LTV

Quando NÃO usar METRIC:

  • Eventos qualitativos: Use EVENT para eventos sem valor numérico
  • Analytics de usuário: Use ANALYTICS para comportamento
  • Logs de debug: Use LOGGER para logs estruturados

Parâmetros Detalhados

name (string, obrigatório)

O que é: Nome único da métrica (use snake_case).

Flow completo para testar:

{
  "name": "Teste METRIC - Name",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "metric_1",
      "type": "metric",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Métrica Total de Usuários",
        "parameters": {
          "name": "total_active_users",
          "value": 1520,
          "unit": "count"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Métrica 'total_active_users' registrada!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 700, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "metric_1" },
    { "source": "metric_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Métrica será registrada com nome "total_active_users"

value (number, obrigatório)

O que é: Valor numérico da métrica.

Flow completo para testar:

{
  "name": "Teste METRIC - Value Dinâmico",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "number_1",
      "type": "number",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Tempo de Resposta",
        "parameters": {
          "message": "Tempo de resposta da API (ms):",
          "variable": "latencia",
          "decimals": 0
        }
      }
    },
    {
      "id": "metric_1",
      "type": "metric",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Registrar Latência",
        "parameters": {
          "name": "api_response_time",
          "value": "{{latencia}}",
          "unit": "milliseconds",
          "type": "histogram"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "⏱️ Latência de {{latencia}}ms registrada!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "number_1" },
    { "source": "number_1", "target": "metric_1" },
    { "source": "metric_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Digite 250 - métrica será registrada com value=250

unit (string, opcional)

O que é: Unidade de medida da métrica.

Padrão: "count"

Unidades comuns: - count - Contagem - milliseconds / seconds / minutes - Tempo - bytes / kilobytes / megabytes - Tamanho - percent - Porcentagem - currency / BRL / USD - Valores monetários - requests_per_second - Taxa

Flow completo para testar:

{
  "name": "Teste METRIC - Units",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "metric_time",
      "type": "metric",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Tempo de Processamento",
        "parameters": {
          "name": "processing_time",
          "value": 1.5,
          "unit": "seconds"
        }
      }
    },
    {
      "id": "metric_size",
      "type": "metric",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Tamanho do Arquivo",
        "parameters": {
          "name": "file_size",
          "value": 2048,
          "unit": "kilobytes"
        }
      }
    },
    {
      "id": "metric_percent",
      "type": "metric",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Taxa de Sucesso",
        "parameters": {
          "name": "success_rate",
          "value": 98.5,
          "unit": "percent"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ 3 métricas com unidades diferentes registradas!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1100, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "metric_time" },
    { "source": "metric_time", "target": "metric_size" },
    { "source": "metric_size", "target": "metric_percent" },
    { "source": "metric_percent", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

type (string, opcional)

O que é: Tipo da métrica para agregação correta.

Padrão: "gauge"

Tipos: - gauge - Valor atual (ex: usuários online, temperatura) - counter - Contador incremental (ex: total de requests) - histogram - Distribuição de valores (ex: latências) - timer - Medição de tempo (ex: duração de operações)

Flow completo para testar tipos:

{
  "name": "Teste METRIC - Types",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "metric_gauge",
      "type": "metric",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Gauge - Usuários Online",
        "parameters": {
          "name": "users_online",
          "value": 42,
          "type": "gauge",
          "unit": "count"
        }
      }
    },
    {
      "id": "metric_counter",
      "type": "metric",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Counter - Total Requests",
        "parameters": {
          "name": "total_requests",
          "value": 150000,
          "type": "counter",
          "unit": "count"
        }
      }
    },
    {
      "id": "metric_histogram",
      "type": "metric",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Histogram - Latência",
        "parameters": {
          "name": "api_latency",
          "value": 125,
          "type": "histogram",
          "unit": "milliseconds"
        }
      }
    },
    {
      "id": "metric_timer",
      "type": "metric",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Timer - Duração",
        "parameters": {
          "name": "flow_duration",
          "value": 3.5,
          "type": "timer",
          "unit": "seconds"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ 4 tipos de métricas registradas:\n- Gauge: usuários online\n- Counter: total requests\n- Histogram: latências\n- Timer: durações"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1300, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "metric_gauge" },
    { "source": "metric_gauge", "target": "metric_counter" },
    { "source": "metric_counter", "target": "metric_histogram" },
    { "source": "metric_histogram", "target": "metric_timer" },
    { "source": "metric_timer", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

dimensions (object, opcional)

O que é: Dimensões para segmentar a métrica (tags/labels).

Padrão: {}

Flow completo para testar:

{
  "name": "Teste METRIC - Dimensions",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "number_1",
      "type": "number",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Valor do Pedido",
        "parameters": {
          "message": "Valor do pedido:",
          "variable": "valor",
          "decimals": 2
        }
      }
    },
    {
      "id": "metric_1",
      "type": "metric",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Pedido com Dimensões",
        "parameters": {
          "name": "order_value",
          "value": "{{valor}}",
          "unit": "BRL",
          "type": "gauge",
          "dimensions": {
            "payment_method": "credit_card",
            "customer_type": "premium",
            "region": "southeast",
            "channel": "whatsapp"
          }
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Confirmar",
        "parameters": {
          "message": "✅ Pedido de R$ {{valor}} registrado!\n\nDimensões:\n- Pagamento: cartão\n- Cliente: premium\n- Região: sudeste\n- Canal: whatsapp"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "number_1" },
    { "source": "number_1", "target": "metric_1" },
    { "source": "metric_1", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Teste: Digite 250.00 - métrica será registrada com todas as dimensões para segmentação

timestamp (string, opcional)

O que é: Timestamp ISO 8601 da métrica.

Padrão: Data/hora atual do sistema

Parâmetros

Campo Tipo Obrigatório Descrição
name string Sim Nome único da métrica (snake_case)
value number Sim Valor numérico da métrica
unit string Não Unidade de medida (padrão: count)
type string Não Tipo da métrica: gauge, counter, histogram, timer (padrão: gauge)
dimensions object Não Dimensões para segmentação (padrão: {})
timestamp string Não Timestamp ISO 8601 (padrão: now)

Exemplo 1: Dashboard de Performance de Flow

Objetivo: Medir performance completa de um flow

JSON para Importar

{
  "name": "Flow Performance Dashboard",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "variable_start",
      "type": "variable",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Marcar Início",
        "parameters": {
          "operation": "set",
          "variables": {
            "start_time": "{{$timestamp}}"
          }
        }
      }
    },
    {
      "id": "metric_started",
      "type": "metric",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Flow Iniciado",
        "parameters": {
          "name": "flow_started",
          "value": 1,
          "type": "counter",
          "dimensions": {
            "flow_name": "checkout",
            "version": "v2"
          }
        }
      }
    },
    {
      "id": "input_1",
      "type": "input",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Nome",
        "parameters": {
          "message": "Seu nome:",
          "variable": "nome"
        }
      }
    },
    {
      "id": "delay_1",
      "type": "delay",
      "position": { "x": 900, "y": 100 },
      "data": {
        "label": "Processar",
        "parameters": {
          "duration": 2,
          "unit": "seconds"
        }
      }
    },
    {
      "id": "variable_end",
      "type": "variable",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Calcular Duração",
        "parameters": {
          "operation": "set",
          "variables": {
            "end_time": "{{$timestamp}}",
            "duration": 2.5
          }
        }
      }
    },
    {
      "id": "metric_duration",
      "type": "metric",
      "position": { "x": 1300, "y": 100 },
      "data": {
        "label": "Duração do Flow",
        "parameters": {
          "name": "flow_duration",
          "value": "{{duration}}",
          "unit": "seconds",
          "type": "timer",
          "dimensions": {
            "flow_name": "checkout",
            "version": "v2",
            "status": "completed"
          }
        }
      }
    },
    {
      "id": "metric_completed",
      "type": "metric",
      "position": { "x": 1500, "y": 100 },
      "data": {
        "label": "Flow Completo",
        "parameters": {
          "name": "flow_completed",
          "value": 1,
          "type": "counter",
          "dimensions": {
            "flow_name": "checkout",
            "version": "v2"
          }
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1700, "y": 100 },
      "data": {
        "label": "Resumo",
        "parameters": {
          "message": "✅ Flow completo, {{nome}}!\n\n📊 Métricas registradas:\n- flow_started: 1\n- flow_duration: {{duration}}s\n- flow_completed: 1"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1900, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "variable_start" },
    { "source": "variable_start", "target": "metric_started" },
    { "source": "metric_started", "target": "input_1" },
    { "source": "input_1", "target": "delay_1" },
    { "source": "delay_1", "target": "variable_end" },
    { "source": "variable_end", "target": "metric_duration" },
    { "source": "metric_duration", "target": "metric_completed" },
    { "source": "metric_completed", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Seu nome:
Usuário: Maria
Sistema: ✅ Flow completo, Maria!

📊 Métricas registradas:
- flow_started: 1
- flow_duration: 2.5s
- flow_completed: 1

Exemplo 2: Métricas de E-commerce

Objetivo: Rastrear métricas de valor de pedidos

JSON para Importar

{
  "name": "E-commerce Metrics",
  "nodes": [
    {
      "id": "start_1",
      "type": "start",
      "position": { "x": 100, "y": 100 },
      "data": { "label": "Início" }
    },
    {
      "id": "number_items",
      "type": "number",
      "position": { "x": 300, "y": 100 },
      "data": {
        "label": "Quantidade",
        "parameters": {
          "message": "Quantos produtos?",
          "variable": "quantidade",
          "min": 1
        }
      }
    },
    {
      "id": "number_value",
      "type": "number",
      "position": { "x": 500, "y": 100 },
      "data": {
        "label": "Valor Total",
        "parameters": {
          "message": "Valor total do pedido:",
          "variable": "valor_total",
          "decimals": 2
        }
      }
    },
    {
      "id": "variable_calc",
      "type": "variable",
      "position": { "x": 700, "y": 100 },
      "data": {
        "label": "Calcular Médias",
        "parameters": {
          "operation": "set",
          "variables": {
            "valor_medio": "{{valor_total / quantidade}}"
          }
        }
      }
    },
    {
      "id": "metric_items",
      "type": "metric",
      "position": { "x": 900, "y": 50 },
      "data": {
        "label": "Items no Pedido",
        "parameters": {
          "name": "order_items_count",
          "value": "{{quantidade}}",
          "unit": "count",
          "type": "gauge"
        }
      }
    },
    {
      "id": "metric_value",
      "type": "metric",
      "position": { "x": 900, "y": 150 },
      "data": {
        "label": "Valor do Pedido",
        "parameters": {
          "name": "order_value",
          "value": "{{valor_total}}",
          "unit": "BRL",
          "type": "gauge",
          "dimensions": {
            "payment_method": "credit_card"
          }
        }
      }
    },
    {
      "id": "metric_avg",
      "type": "metric",
      "position": { "x": 1100, "y": 100 },
      "data": {
        "label": "Ticket Médio",
        "parameters": {
          "name": "average_item_value",
          "value": "{{valor_medio}}",
          "unit": "BRL",
          "type": "gauge"
        }
      }
    },
    {
      "id": "message_1",
      "type": "message",
      "position": { "x": 1300, "y": 100 },
      "data": {
        "label": "Resumo",
        "parameters": {
          "message": "🛒 PEDIDO REGISTRADO\n\n📊 Métricas:\n- Items: {{quantidade}}\n- Total: R$ {{valor_total}}\n- Média por item: R$ {{valor_medio}}\n\n✅ Dados enviados para dashboard!"
        }
      }
    },
    {
      "id": "end_1",
      "type": "end",
      "position": { "x": 1500, "y": 100 },
      "data": { "label": "Fim" }
    }
  ],
  "edges": [
    { "source": "start_1", "target": "number_items" },
    { "source": "number_items", "target": "number_value" },
    { "source": "number_value", "target": "variable_calc" },
    { "source": "variable_calc", "target": "metric_items" },
    { "source": "variable_calc", "target": "metric_value" },
    { "source": "metric_items", "target": "metric_avg" },
    { "source": "metric_value", "target": "metric_avg" },
    { "source": "metric_avg", "target": "message_1" },
    { "source": "message_1", "target": "end_1" }
  ]
}

Saída esperada:

Sistema: Quantos produtos?
Usuário: 3
Sistema: Valor total do pedido:
Usuário: 450.00
Sistema: 🛒 PEDIDO REGISTRADO

📊 Métricas:
- Items: 3
- Total: R$ 450.00
- Média por item: R$ 150.00

✅ Dados enviados para dashboard!

Resposta do Node

{
  "success": true,
  "action": "metric_recorded",
  "metric": {
    "name": "order_value",
    "value": 450.00,
    "unit": "BRL",
    "type": "gauge",
    "dimensions": {
      "payment_method": "credit_card",
      "region": "southeast"
    },
    "timestamp": "2025-01-15T10:30:00.000Z",
    "context": {
      "flowId": "flow_789",
      "userId": "user_456",
      "sessionId": "session_123"
    }
  },
  "timestamp": "2025-01-15T10:30:00.000Z"
}

Tipos de Métricas Explicados

Gauge (Medidor)

Valor atual que pode subir ou descer. - Exemplos: Usuários online, temperatura, estoque - Uso: Snapshots do estado atual

Counter (Contador)

Valor que sempre aumenta. - Exemplos: Total de requests, vendas acumuladas - Uso: Contadores monotônicos

Histogram (Distribuição)

Distribuição de valores para calcular percentis. - Exemplos: Latências de API, tamanhos de arquivo - Uso: Análise de distribuição (p50, p95, p99)

Timer (Temporizador)

Duração de operações. - Exemplos: Tempo de processamento, duração de flows - Uso: Medição de performance temporal

Integração com Plataformas

Este node pode ser integrado com:

  • CloudWatch (AWS)
  • Datadog
  • New Relic
  • Prometheus
  • Grafana
  • InfluxDB

Boas Práticas

SIM: - Use nomes descritivos em snake_case - Sempre inclua unit apropriada - Use dimensions para segmentação - Escolha type correto (gauge/counter/histogram/timer) - Documente suas métricas em um catálogo - Use valores numéricos puros (não strings)

NÃO: - Não crie métricas demais (causa overhead) - Não use nomes genéricos ("metric1", "value") - Não mude tipo de métrica existente - Não abuse de dimensions (máximo 10-15) - Não registre valores não-numéricos

Dicas

💡 Nomenclatura: Use padrão objeto_acao_metrica (ex: api_request_duration, order_value_total)

💡 Dimensions vs Métricas: Use dimensions para variações da mesma métrica, não crie métricas separadas

💡 Agregações: Gauge = último valor, Counter = soma, Histogram = percentis, Timer = média/max/min

💡 Alertas: Configure alertas baseados em thresholds das métricas

💡 Dashboards: Agrupe métricas relacionadas em dashboards temáticos

💡 Cálculos: Use VARIABLE para calcular valores antes de registrar métrica

Próximo Node

ANALYTICS - Rastrear eventos de usuário → LOGGER - Logs estruturados → EVENT - Rastrear eventos de negócio → TRACKING - Rastreamento avançado