Metrics Module

Transform raw tracking data into actionable insights with comprehensive metrics including latency analysis, throughput calculations, gas usage, and system health indicators.

Overview

The Metrics Module analyzes tracking data to provide operational intelligence for cross-chain messaging. It generates structured metrics that help you understand system performance and identify potential issues.

Core Metrics

  • • Latency analysis with percentiles
  • • Throughput and success rates
  • • Gas usage statistics
  • • Message timing analysis

Health Monitoring

  • • System status determination
  • • Error rate analysis
  • • Health alerts generation
  • • Performance recommendations

generateMetrics

The main function that processes tracking data and returns comprehensive metrics. It analyzes all successful and failed tracking attempts to provide insights.

Function Signature

generateMetrics(trackingResults: TrackingResult[], config?: MetricsConfig): InteropMetrics
import { 
  generateMetrics, 
  InteropMetrics,
  TrackingResult,
  MetricsConfig
} from '@wakeuplabs/op-interop-alerts-sdk';

// Sample tracking results (normally collected from startTracking)
const trackingResults: TrackingResult[] = [
  // ... your tracking results from monitoring
];

// Optional configuration for metrics generation
const metricsConfig: MetricsConfig = {
  expectedLatencyMs: 30000,    // Expected latency threshold (30 seconds)
  severeLatencyMs: 120000,     // Severe latency threshold (2 minutes)
  expectedGasLimit: 100000n,   // Expected gas limit
  healthThresholds: {
    successRateWarning: 0.95,  // Warn if success rate < 95%
    successRateCritical: 0.90, // Critical if success rate < 90%
    latencyWarningMs: 60000,   // Warn if latency > 1 minute
    latencyCriticalMs: 180000  // Critical if latency > 3 minutes
  }
};

// Generate comprehensive metrics
const metrics: InteropMetrics = generateMetrics(trackingResults, metricsConfig);

// Access different metric categories
console.log('=== System Status ===');
console.log('Interop Status:', metrics.status.interopStatus);
console.log('Health Level:', metrics.status.healthLevel);
console.log('Timing Status:', metrics.status.timingStatus);

console.log('\n=== Throughput Metrics ===');
const throughput = metrics.coreMetrics.throughput;
console.log(`Total Messages: ${throughput.totalMessages}`);
console.log(`Success Rate: ${throughput.successRate.toFixed(2)}%`);
console.log(`Messages/Hour: ${throughput.messagesPerHour.toFixed(2)}`);

console.log('\n=== Latency Metrics ===');
const latency = metrics.coreMetrics.latency;
console.log(`Average: ${(latency.averageLatencyMs / 1000).toFixed(2)}s`);
console.log(`Median: ${(latency.medianLatencyMs / 1000).toFixed(2)}s`);
console.log(`P95: ${(latency.p95LatencyMs / 1000).toFixed(2)}s`);
console.log(`P99: ${(latency.p99LatencyMs / 1000).toFixed(2)}s`);

console.log('\n=== Gas Metrics ===');
const gas = metrics.coreMetrics.gas;
console.log(`Avg Send Gas: ${gas.averageSendGas.toString()}`);
console.log(`Avg Relay Gas: ${gas.averageRelayGas.toString()}`);
console.log(`Total Gas Used: ${gas.totalGasUsed.toString()}`);

console.log('\n=== Health Summary ===');
if (metrics.health.alerts.length > 0) {
  console.log('Active Alerts:');
  metrics.health.alerts.forEach((alert, index) => {
    console.log(`  ${index + 1}. [${alert.level}] ${alert.type}: ${alert.message}`);
  });
}

if (metrics.health.recommendations.length > 0) {
  console.log('\nRecommendations:');
  metrics.health.recommendations.forEach((rec, index) => {
    console.log(`  ${index + 1}. ${rec}`);
  });
}

Complete Example

Here's a complete example that combines tracking with metrics generation:

import { 
  startTracking, 
  generateMetrics,
  TrackingResult,
  InteropMetrics
} from '@wakeuplabs/op-interop-alerts-sdk';
import { chainsInfoMock } from '@wakeuplabs/op-interop-alerts-sdk/config';

const pksInfo = {
  origin: process.env.ORIGIN_PRIVATE_KEY as `0x${string}`,
  destination: process.env.DESTINATION_PRIVATE_KEY as `0x${string}`,
};

// Store tracking results for metrics generation
const trackingResults: TrackingResult[] = [];
const METRICS_THRESHOLD = 5; // Generate metrics after 5 data points

const trackingCallback = (result: TrackingResult) => {
  console.log(`[${result.timestamp.toISOString()}] Tracking: ${result.success ? '✅' : '❌'}`);
  
  // Store the result
  trackingResults.push(result);
  
  // Generate metrics when we have enough data
  if (trackingResults.length >= METRICS_THRESHOLD) {
    generateAndDisplayMetrics();
  }
};

function generateAndDisplayMetrics() {
  try {
    const metrics: InteropMetrics = generateMetrics(trackingResults);
    
    console.log('\n📊 === METRICS REPORT ===');
    console.log(`Status: ${metrics.status.interopStatus} (${metrics.status.healthLevel})`);
    console.log(`Data Points: ${metrics.status.totalDataPoints}`);
    
    // Throughput summary
    const throughput = metrics.coreMetrics.throughput;
    console.log(`\n🚀 Throughput: ${throughput.successRate.toFixed(1)}% success rate`);
    console.log(`   Messages: ${throughput.successfulMessages}/${throughput.totalMessages}`);
    console.log(`   Rate: ${throughput.messagesPerHour.toFixed(1)} msg/hour`);
    
    // Latency summary
    const latency = metrics.coreMetrics.latency;
    console.log(`\n⏱️  Latency: ${(latency.averageLatencyMs / 1000).toFixed(1)}s avg`);
    console.log(`   P95: ${(latency.p95LatencyMs / 1000).toFixed(1)}s`);
    console.log(`   Range: ${(latency.minLatencyMs / 1000).toFixed(1)}s - ${(latency.maxLatencyMs / 1000).toFixed(1)}s`);
    
    // Gas summary
    const gas = metrics.coreMetrics.gas;
    console.log(`\n⛽ Gas: ${gas.averageSendGas.toString()} send, ${gas.averageRelayGas.toString()} relay`);
    
    // Health alerts
    if (metrics.health.alerts.length > 0) {
      console.log(`\n🚨 Alerts:`);
      metrics.health.alerts.forEach(alert => {
        console.log(`   [${alert.level}] ${alert.message}`);
      });
    }
    
    // Recommendations
    if (metrics.health.recommendations.length > 0) {
      console.log(`\n💡 Recommendations:`);
      metrics.health.recommendations.forEach(rec => {
        console.log(`${rec}`);
      });
    }
    
    console.log('=== END REPORT ===\n');
    
  } catch (error) {
    console.error('❌ Error generating metrics:', error);
  }
}

// Start monitoring with metrics
async function main() {
  console.log('🚀 Starting monitoring with metrics generation...');
  console.log(`📊 Will generate metrics after ${METRICS_THRESHOLD} data points\n`);
  
  try {
    await startTracking(chainsInfoMock, pksInfo, trackingCallback, 5);
  } catch (error) {
    console.error('❌ Monitoring failed:', error);
  }
}

main();

Next Steps

Now that you understand metrics generation, learn how to set up intelligent alerts based on your metrics: