Principles and Implementation of Frontend Monitoring System Explained in Detail

Principles and Implementation of Frontend Monitoring System Explained in Detail

I. Overview of Monitoring Systems
A frontend monitoring system is used to collect, analyze, and alert on various types of runtime data from web applications. It mainly includes three categories of monitoring:

  1. Performance Monitoring: Core Web Vitals such as FP/FCP/LCP
  2. Error Monitoring: JavaScript errors, resource loading failures, etc.
  3. Behavior Monitoring: PV/UV, user interaction paths, etc.

II. Principles of Data Collection

  1. Performance Data Collection
// Use the Performance API to obtain performance metrics
const performance = window.performance;
const timing = performance.timing;

// Calculate page load time
const loadTime = timing.loadEventEnd - timing.navigationStart;

// Core Web Vitals collection (requires compatibility handling)
const observer = new PerformanceObserver((list) => {
  list.getEntries().forEach(entry => {
    if (entry.name === 'first-contentful-paint') {
      console.log('FCP:', entry.startTime);
    }
  });
});
observer.observe({type: 'paint', buffered: true});
  1. Error Collection Scheme
// JS error listener
window.addEventListener('error', (e) => {
  const errorLog = {
    type: 'javascript',
    message: e.message,
    filename: e.filename,
    lineno: e.lineno,
    colno: e.colno,
    stack: e.error?.stack,
    timestamp: Date.now()
  };
  sendToServer(errorLog);
}, true);

// Promise error capture
window.addEventListener('unhandledrejection', (e) => {
  const errorLog = {
    type: 'promise',
    reason: e.reason?.toString(),
    timestamp: Date.now()
  };
  sendToServer(errorLog);
});

III. Data Transmission Optimization

  1. Batch Reporting Mechanism
class Monitor {
  constructor() {
    this.cache = [];
    this.maxCache = 10;
    this.delay = 5000;
  }
  
  push(data) {
    this.cache.push({...data, timestamp: Date.now()});
    if (this.cache.length >= this.maxCache) {
      this.flush();
    }
  }
  
  flush() {
    if (this.cache.length === 0) return;
    
    // Prioritize sendBeacon, fall back to fetch on failure
    const blob = new Blob([JSON.stringify(this.cache)]);
    if (!navigator.sendBeacon('/api/monitor', blob)) {
      fetch('/api/monitor', {
        method: 'POST',
        body: JSON.stringify(this.cache),
        keepalive: true // Ensure sending during page unload
      });
    }
    this.cache = [];
  }
}
  1. Sampling and Deduplication Strategies
// Error sampling (1% sampling rate)
function shouldSample() {
  return Math.random() < 0.01;
}

// Error signature deduplication
function generateErrorSignature(error) {
  return `${error.message}-${error.filename}-${error.lineno}`;
}

const seenErrors = new Set();
function deduplicateError(error) {
  const signature = generateErrorSignature(error);
  if (seenErrors.has(signature)) return false;
  seenErrors.add(signature);
  return true;
}

IV. Data Storage and Analysis

  1. Log Storage Structure
CREATE TABLE error_logs (
  id BIGINT AUTO_INCREMENT,
  project_id VARCHAR(50),
  error_type ENUM('js', 'resource', 'promise'),
  message TEXT,
  stack_trace TEXT,
  user_agent TEXT,
  url VARCHAR(500),
  timestamp DATETIME,
  PRIMARY KEY(id),
  INDEX idx_project_time(project_id, timestamp)
);
  1. Aggregation Analysis Example
-- Error trend analysis
SELECT 
  DATE(timestamp) as date,
  error_type,
  COUNT(*) as count
FROM error_logs 
WHERE timestamp > NOW() - INTERVAL 7 DAY
GROUP BY date, error_type;

V. Visualization and Alerting

  1. Key Metrics Dashboard

    • Error Rate = Error Count / PV
    • Performance Compliance Rate = Percentage of sessions with LCP < 2.5s
    • Resource Error Rate = Failed Resource Loads / Total Resources
  2. Intelligent Alert Rules

// Sliding window-based alert detection
class AlertSystem {
  constructor(threshold = 0.05, windowSize = 1000) {
    this.errors = [];
    this.threshold = threshold;
    this.windowSize = windowSize;
  }
  
  checkAlert(currentErrorRate) {
    // Error rate exceeds threshold for 5 consecutive minutes
    this.errors.push(currentErrorRate > this.threshold ? 1 : 0);
    if (this.errors.length > this.windowSize) {
      this.errors.shift();
    }
    
    const recentErrors = this.errors.slice(-300); // Last 5 minutes
    const errorCount = recentErrors.reduce((a, b) => a + b);
    return errorCount / recentErrors.length > 0.8;
  }
}

VI. Practical Considerations

  1. Exception Handling for Monitoring Code Itself
try {
  // Monitoring logic
} catch (e) {
  // Prevent monitoring code from crashing the main business
  console.warn('Monitor error:', e);
}
  1. Performance Impact Control

    • Use Web Workers for complex calculations
    • Avoid synchronous operations blocking the main thread
    • Set reasonable sampling frequencies
  2. Privacy Protection and Compliance

    • Automatically filter sensitive information (passwords, ID numbers, etc.)
    • Provide user opt-out mechanisms
    • Comply with data regulations like GDPR

Through this complete monitoring system, you can grasp the health status of your application in real-time, quickly locate issues, and continuously optimize user experience. Advanced features such as log search and root cause analysis should also be considered during actual deployment.