2.前端监控---异常监控

28 阅读2分钟

1. 核心功能

  • 捕获 JavaScript 运行时错误(window.onerror)。
  • 捕获资源加载失败(<img><script><link> 等)。
  • 捕获未处理的 Promise 拒绝(unhandledrejection)。
  • 捕获框架级别的错误(如 React、Vue 的错误边界)。
  • 性能优化:避免监控代码本身引发性能问题。
  • 扩展性:支持自定义错误处理逻辑。

2. 代码实现

javascript

复制

class ErrorMonitor {
    constructor() {
        this.init();
    }

    // 初始化监控
    init() {
        this.setupGlobalErrorHandlers();
        this.setupResourceErrorHandlers();
        this.setupPromiseRejectionHandlers();
    }

    // 捕获全局 JavaScript 运行时错误
    setupGlobalErrorHandlers() {
        window.onerror = (message, source, lineno, colno, error) => {
            const errorInfo = {
                type: 'runtime',
                message: message,
                source: source,
                lineno: lineno,
                colno: colno,
                stack: error ? error.stack : null,
                timestamp: new Date().toISOString()
            };
            this.handleError(errorInfo);
            // 返回 true 阻止默认错误处理
            return true;
        };
    }

    // 捕获资源加载失败
    setupResourceErrorHandlers() {
        window.addEventListener('error', (event) => {
            const target = event.target;
            if (target && (target.tagName === 'IMG' || target.tagName === 'SCRIPT' || target.tagName === 'LINK')) {
                const resourceErrorInfo = {
                    type: 'resource',
                    tagName: target.tagName,
                    src: target.src || target.href,
                    message: event.message,
                    timestamp: new Date().toISOString()
                };
                this.handleError(resourceErrorInfo);
            }
        }, true); // 使用捕获阶段监听
    }

    // 捕获未处理的 Promise 拒绝
    setupPromiseRejectionHandlers() {
        window.addEventListener('unhandledrejection', (event) => {
            const promiseErrorInfo = {
                type: 'promise',
                reason: event.reason,
                message: event.reason?.message || 'Unhandled promise rejection',
                timestamp: new Date().toISOString()
            };
            this.handleError(promiseErrorInfo);
        });
    }

    // 处理错误(可扩展)
    handleError(errorInfo) {
        // 这里可以添加自定义的错误处理逻辑
        // 例如:过滤错误、格式化错误信息、触发回调等
        console.error('Captured Error:', errorInfo);

        // 如果需要扩展,可以触发事件或调用插件
        if (this.onError) {
            this.onError(errorInfo);
        }
    }

    // 注册自定义错误处理函数
    onError(callback) {
        if (typeof callback === 'function') {
            this.onError = callback;
        }
    }
}

// 初始化异常监控
const errorMonitor = new ErrorMonitor();

// 示例:自定义错误处理
errorMonitor.onError((errorInfo) => {
    console.log('Custom Error Handler:', errorInfo);
});

3. 功能扩展

支持 React 错误边界

React 提供了错误边界(Error Boundary)机制,可以捕获组件树中的 JavaScript 错误。我们可以将其集成到监控系统中。

javascript

复制

class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false };
    }

    static getDerivedStateFromError(error) {
        return { hasError: true };
    }

    componentDidCatch(error, errorInfo) {
        // 将 React 错误信息传递给监控系统
        errorMonitor.handleError({
            type: 'react',
            message: error.message,
            stack: error.stack,
            componentStack: errorInfo.componentStack,
            timestamp: new Date().toISOString()
        });
    }

    render() {
        if (this.state.hasError) {
            return <h1>Something went wrong.</h1>;
        }
        return this.props.children;
    }
}
支持 Vue 错误处理

Vue 提供了全局错误处理钩子 errorHandler,可以捕获 Vue 组件中的错误。

javascript

复制

Vue.config.errorHandler = (error, vm, info) => {
    errorMonitor.handleError({
        type: 'vue',
        message: error.message,
        stack: error.stack,
        component: vm?.$options?.name,
        lifecycleHook: info,
        timestamp: new Date().toISOString()
    });
};

4. 性能优化

  • 避免阻塞主线程:错误处理逻辑应尽量轻量,避免同步操作。
  • 采样率控制:在高并发场景下,可以通过采样率控制减少监控数据量。
  • 懒加载监控代码:将监控代码拆分为独立模块,按需加载。

5. 总结

这个企业级前端异常监控方案具有以下特点:

  1. 全面性:覆盖 JavaScript 运行时错误、资源加载失败、Promise 拒绝、React/Vue 框架错误。
  2. 扩展性:支持自定义错误处理逻辑,方便集成到现有系统中。
  3. 高性能:避免监控代码本身成为性能瓶颈。
  4. 易用性:提供清晰的 API,支持自定义错误处理函数。