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:
- Performance Monitoring: Core Web Vitals such as FP/FCP/LCP
- Error Monitoring: JavaScript errors, resource loading failures, etc.
- Behavior Monitoring: PV/UV, user interaction paths, etc.
II. Principles of Data Collection
- 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});
- 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
- 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 = [];
}
}
- 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
- 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)
);
- 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
-
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
-
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
- Exception Handling for Monitoring Code Itself
try {
// Monitoring logic
} catch (e) {
// Prevent monitoring code from crashing the main business
console.warn('Monitor error:', e);
}
-
Performance Impact Control
- Use Web Workers for complex calculations
- Avoid synchronous operations blocking the main thread
- Set reasonable sampling frequencies
-
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.