umi错误收集:Sentry错误监控与告警

umi错误收集:Sentry错误监控与告警

【免费下载链接】umi A framework in react community ✨ 【免费下载链接】umi 项目地址: https://gitcode.com/GitHub_Trending/um/umi

前言

在现代前端应用开发中,错误监控是保证应用稳定性的关键环节。umi作为React社区的主流框架,提供了完善的错误处理机制,但生产环境中的错误监控和告警需要更专业的解决方案。本文将详细介绍如何在umi项目中集成Sentry,实现全方位的错误监控与告警系统。

为什么需要专业的错误监控?

传统错误处理的局限性

// 传统的try-catch错误处理
try {
  // 业务逻辑代码
  const result = await apiCall();
} catch (error) {
  console.error('API调用失败:', error);
  message.error('操作失败,请重试');
}

传统错误处理方式存在以下问题:

  • ❌ 无法捕获异步错误
  • ❌ 无法监控运行时异常
  • ❌ 缺乏错误上下文信息
  • ❌ 无法实现实时告警
  • ❌ 错误数据难以统计分析

Sentry的优势

Sentry作为业界领先的错误监控平台,提供:

  • ✅ 实时错误捕获和报告
  • ✅ 完整的错误上下文信息
  • ✅ 智能错误分组和去重
  • ✅ 多维度错误分析
  • ✅ 灵活的告警机制
  • ✅ 性能监控集成

umi项目Sentry集成方案

环境准备

首先安装Sentry相关依赖:

npm install @sentry/react @sentry/tracing
# 或
yarn add @sentry/react @sentry/tracing

基础配置

在umi项目中创建Sentry配置文件:

// src/utils/sentry.ts
import * as Sentry from '@sentry/react';
import { BrowserTracing } from '@sentry/tracing';

export const initSentry = () => {
  if (process.env.NODE_ENV === 'production') {
    Sentry.init({
      dsn: '你的Sentry DSN',
      integrations: [new BrowserTracing()],
      tracesSampleRate: 0.2,
      environment: process.env.NODE_ENV,
      release: process.env.APP_VERSION,
    });
  }
};

// 自定义错误处理器
export const captureException = (error: Error, context?: any) => {
  if (process.env.NODE_ENV === 'production') {
    Sentry.captureException(error, {
      extra: context,
    });
  } else {
    console.error('Development Error:', error, context);
  }
};

umi应用入口集成

在应用入口文件中初始化Sentry:

// src/app.tsx
import { initSentry, captureException } from './utils/sentry';

// 初始化Sentry
export function render(oldRender: Function) {
  initSentry();
  oldRender();
}

// 错误边界处理
export function onError(error: Error) {
  captureException(error, {
    type: 'app-error-boundary',
  });
}

// 请求错误处理
export const request = {
  errorConfig: {
    errorHandler: (error: any) => {
      captureException(error, {
        type: 'request-error',
        url: error.config?.url,
        method: error.config?.method,
      });
    },
  },
};

错误监控策略设计

错误分类体系

mermaid

错误级别定义

错误级别描述处理策略
CRITICAL致命错误,导致应用崩溃立即告警,最高优先级处理
ERROR严重错误,影响核心功能快速响应,24小时内修复
WARNING警告级别错误监控观察,定期处理
INFO信息级别异常记录日志,无需立即处理

高级错误处理技巧

React错误边界集成

// src/components/ErrorBoundary.tsx
import React from 'react';
import { captureException } from '../utils/sentry';

interface Props {
  children: React.ReactNode;
  fallback?: React.ReactNode;
}

interface State {
  hasError: boolean;
}

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

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

  componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
    captureException(error, {
      componentStack: errorInfo.componentStack,
      type: 'react-error-boundary',
    });
  }

  render() {
    if (this.state.hasError) {
      return this.props.fallback || (
        <div style={{ padding: 20, textAlign: 'center' }}>
          <h2>😵 页面出现了一些问题</h2>
          <p>我们已经记录了这个问题,将会尽快修复</p>
          <button onClick={() => window.location.reload()}>
            重新加载页面
          </button>
        </div>
      );
    }

    return this.props.children;
  }
}

export default ErrorBoundary;

路由级别错误监控

// src/layouts/BasicLayout.tsx
import { useEffect } from 'react';
import { useLocation } from 'umi';
import { captureException } from '../utils/sentry';

const BasicLayout: React.FC = ({ children }) => {
  const location = useLocation();

  useEffect(() => {
    // 监控路由切换错误
    const handleRouteError = (error: Error) => {
      captureException(error, {
        type: 'route-error',
        pathname: location.pathname,
      });
    };

    window.addEventListener('error', handleRouteError);
    return () => window.removeEventListener('error', handleRouteError);
  }, [location.pathname]);

  return <div>{children}</div>;
};

export default BasicLayout;

性能监控集成

性能数据采集

// src/utils/performance.ts
import { captureException } from './sentry';

export const monitorPerformance = () => {
  if ('performance' in window) {
    // 监控关键性能指标
    const observePerformance = () => {
      const navigationTiming = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
      
      if (navigationTiming) {
        const metrics = {
          dns: navigationTiming.domainLookupEnd - navigationTiming.domainLookupStart,
          tcp: navigationTiming.connectEnd - navigationTiming.connectStart,
          request: navigationTiming.responseStart - navigationTiming.requestStart,
          response: navigationTiming.responseEnd - navigationTiming.responseStart,
          domReady: navigationTiming.domContentLoadedEventEnd - navigationTiming.navigationStart,
          load: navigationTiming.loadEventEnd - navigationTiming.navigationStart,
        };

        // 性能异常告警
        if (metrics.load > 5000) {
          captureException(new Error('页面加载性能异常'), {
            type: 'performance-slow',
            metrics,
            url: window.location.href,
          });
        }
      }
    };

    // 在页面加载完成后监控性能
    if (document.readyState === 'complete') {
      observePerformance();
    } else {
      window.addEventListener('load', observePerformance);
    }
  }
};

告警策略配置

Sentry告警规则

# sentry-alert-rules.yml
- name: 前端致命错误告警
  conditions:
    - firstSeenEvent
    - level: error
    - environment: production
  actions:
    - type: email
      targetType: user
      targetIdentifier: "dev-team@company.com"
    - type: slack
      channel: "#frontend-alerts"

- name: API请求失败率告警
  conditions:
    - issue.category: performance
    - measurement: [http.error_rate] > 0.1
    - timeWindow: 1h
  actions:
    - type: pagerduty
      service: frontend-service

自定义告警逻辑

// src/utils/alerting.ts
import { captureException } from './sentry';

interface AlertConfig {
  threshold: number;
  timeWindow: number;
  alertChannel: string;
}

export class ErrorAlertSystem {
  private errorCount: number = 0;
  private lastAlertTime: number = 0;

  constructor(private config: AlertConfig) {}

  trackError(error: Error) {
    this.errorCount++;
    
    const now = Date.now();
    if (this.errorCount >= this.config.threshold && 
        now - this.lastAlertTime > this.config.timeWindow) {
      this.triggerAlert(error);
      this.lastAlertTime = now;
      this.errorCount = 0;
    }
  }

  private triggerAlert(error: Error) {
    // 发送到Sentry并触发告警
    captureException(error, {
      type: 'alert-triggered',
      count: this.errorCount,
      threshold: this.config.threshold,
    });

    // 额外的告警通道(可选)
    this.sendToAlertChannel(error);
  }

  private sendToAlertChannel(error: Error) {
    // 集成企业微信、钉钉、Slack等告警通道
    console.log(`Alert sent to ${this.config.alertChannel}:`, error.message);
  }
}

实战案例:电商平台错误监控

场景分析

mermaid

关键监控指标

监控点错误类型告警阈值处理优先级
首页加载资源加载错误> 5%P0
商品详情页API 404错误> 10次/分钟P1
购物车JavaScript执行错误任何错误P0
支付流程网络超时> 30%P0
用户登录认证错误> 20次/分钟P1

最佳实践总结

配置优化建议

  1. 环境区分:开发、测试、生产环境使用不同的Sentry项目
  2. 采样率控制:生产环境设置合适的tracesSampleRate(0.1-0.2)
  3. 用户信息关联:集成用户信息便于问题排查
  4. 版本管理:关联代码版本号,便于定位问题版本

监控覆盖 Checklist

  •  JavaScript运行时错误
  •  React渲染错误
  •  资源加载失败
  •  API请求异常
  •  用户交互异常
  •  性能指标异常
  •  自定义业务错误

告警响应流程

mermaid

结语

通过Sentry与umi的深度集成,我们可以构建一个完整的前端错误监控体系。这不仅能够帮助开发团队快速发现和修复问题,还能通过数据驱动的方式持续优化应用性能和用户体验。记住,好的错误监控系统不是等到用户投诉才发现问题,而是要在用户感知之前就解决问题。

【免费下载链接】umi A framework in react community ✨ 【免费下载链接】umi 项目地址: https://gitcode.com/GitHub_Trending/um/umi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值