前端Sentry数据分析与可视化:构建智能化监控仪表板

发布于:2025-08-29 ⋅ 阅读:(16) ⋅ 点赞:(0)

前端Sentry数据分析与可视化:构建智能化监控仪表板

在现代前端开发中,仅仅收集错误数据是不够的,更重要的是如何有效地分析和可视化这些数据,从中获得有价值的洞察。本文将深入探讨如何基于Sentry构建智能化的监控仪表板,实现数据的深度分析和可视化展示。

一、Sentry数据分析基础架构

1.1 数据收集与预处理系统

// dataCollectionSystem.js
import * as Sentry from '@sentry/browser';
import { BrowserTracing } from '@sentry/tracing';

// 数据收集与预处理系统
export class DataCollectionSystem {
  constructor(options = {}) {
    this.options = {
      enableAdvancedMetrics: true,
      enableUserBehaviorTracking: true,
      enablePerformanceAnalytics: true,
      dataRetentionDays: 30,
      batchSize: 100,
      flushInterval: 5000, // 5秒
      ...options
    };
    
    this.dataBuffer = [];
    this.metricsCache = new Map();
    this.userSessions = new Map();
    this.performanceMetrics = new Map();
    
    this.setupDataCollection();
    this.startDataProcessing();
  }
  
  setupDataCollection() {
    // 增强Sentry配置
    Sentry.init({
      dsn: process.env.REACT_APP_SENTRY_DSN,
      environment: process.env.NODE_ENV,
      integrations: [
        new BrowserTracing({
          // 自定义性能监控
          beforeNavigate: context => {
            return {
              ...context,
              // 添加自定义标签
              tags: {
                ...context.tags,
                navigationSource: this.getNavigationSource(),
                userSegment: this.getUserSegment(),
                deviceType: this.getDeviceType()
              }
            };
          }
        })
      ],
      tracesSampleRate: 0.1,
      
      // 自定义事件处理器
      beforeSend: (event) => {
        return this.preprocessEvent(event);
      },
      
      // 自定义面包屑处理器
      beforeBreadcrumb: (breadcrumb) => {
        return this.preprocessBreadcrumb(breadcrumb);
      }
    });
    
    // 设置全局事件监听器
    this.setupGlobalEventListeners();
  }
  
  // 预处理事件数据
  preprocessEvent(event) {
    // 添加自定义数据
    event.extra = {
      ...event.extra,
      sessionId: this.getCurrentSessionId(),
      userJourney: this.getUserJourney(),
      performanceContext: this.getPerformanceContext(),
      businessContext: this.getBusinessContext()
    };
    
    // 添加自定义标签
    event.tags = {
      ...event.tags,
      errorCategory: this.categorizeError(event),
      impactLevel: this.calculateImpactLevel(event),
      userType: this.getUserType(),
      featureFlag: this.getActiveFeatureFlags()
    };
    
    // 缓存事件数据用于分析
    this.cacheEventData(event);
    
    return event;
  }
  
  // 预处理面包屑数据
  preprocessBreadcrumb(breadcrumb) {
    // 增强面包屑数据
    breadcrumb.data = {
      ...breadcrumb.data,
      sessionTime: Date.now() - this.getSessionStartTime(),
      pageLoadTime: this.getPageLoadTime(),
      userInteractionCount: this.getUserInteractionCount()
    };
    
    // 缓存用户行为数据
    this.cacheUserBehavior(breadcrumb);
    
    return breadcrumb;
  }
  
  // 设置全局事件监听器
  setupGlobalEventListeners() {
    // 监听页面性能
    if ('PerformanceObserver' in window) {
      this.setupPerformanceObserver();
    }
    
    // 监听用户交互
    this.setupUserInteractionTracking();
    
    // 监听网络状态
    this.setupNetworkMonitoring();
    
    // 监听内存使用
    this.setupMemoryMonitoring();
  }
  
  // 设置性能观察器
  setupPerformanceObserver() {
    // 监听导航性能
    const navObserver = new PerformanceObserver((list) => {
      list.getEntries().forEach(entry => {
        this.collectNavigationMetrics(entry);
      });
    });
    navObserver.observe({ entryTypes: ['navigation'] });
    
    // 监听资源加载性能
    const resourceObserver = new PerformanceObserver((list) => {
      list.getEntries().forEach(entry => {
        this.collectResourceMetrics(entry);
      });
    });
    resourceObserver.observe({ entryTypes: ['resource'] });
    
    // 监听长任务
    const longTaskObserver = new PerformanceObserver((list) => {
      list.getEntries().forEach(entry => {
        this.collectLongTaskMetrics(entry);
      });
    });
    longTaskObserver.observe({ entryTypes: ['longtask'] });
    
    // 监听布局偏移
    const clsObserver = new PerformanceObserver((list) => {
      list.getEntries().forEach(entry => {
        this.collectLayoutShiftMetrics(entry);
      });
    });
    clsObserver.observe({ entryTypes: ['layout-shift'] });
  }
  
  // 收集导航性能指标
  collectNavigationMetrics(entry) {
    const metrics = {
      type: 'navigation',
      timestamp: Date.now(),
      url: entry.name,
      duration: entry.duration,
      domContentLoaded: entry.domContentLoadedEventEnd - entry.domContentLoadedEventStart,
      loadComplete: entry.loadEventEnd - entry.loadEventStart,
      firstPaint: this.getFirstPaint(),
      firstContentfulPaint: this.getFirstContentfulPaint(),
      largestContentfulPaint: this.getLargestContentfulPaint(),
      firstInputDelay: this.getFirstInputDelay(),
      cumulativeLayoutShift: this.getCumulativeLayoutShift(),
      timeToInteractive: this.getTimeToInteractive()
    };
    
    this.addToDataBuffer('performance', metrics);
    
    // 发送到Sentry
    Sentry.addBreadcrumb({
      category: 'performance',
      message: 'Navigation performance collected',
      level: 'info',
      data: metrics
    });
  }
  
  // 收集资源加载指标
  collectResourceMetrics(entry) {
    const metrics = {
      type: 'resource',
      timestamp: Date.now(),
      name: entry.name,
      duration: entry.duration,
      size: entry.transferSize,
      resourceType: this.getResourceType(entry.name),
      initiatorType: entry.initiatorType,
      responseStart: entry.responseStart,
      responseEnd: entry.responseEnd
    };
    
    this.addToDataBuffer('resource', metrics);
  }
  
  // 收集长任务指标
  collectLongTaskMetrics(entry) {
    const metrics = {
      type: 'longtask',
      timestamp: Date.now(),
      duration: entry.duration,
      startTime: entry.startTime,
      attribution: entry.attribution
    };
    
    this.addToDataBuffer('longtask', metrics);
    
    // 如果长任务超过阈值,发送警告
    if (entry.duration > 100) {
      Sentry.captureMessage(
        `Long task detected: ${entry.duration}ms`,
        'warning',
        {
          tags: {
            category: 'performance',
            type: 'longtask'
          },
          extra: metrics
        }
      );
    }
  }
  
  // 收集布局偏移指标
  collectLayoutShiftMetrics(entry) {
    if (!entry.hadRecentInput) {
      const metrics = {
        type: 'layout-shift',
        timestamp: Date.now(),
        value: entry.value,
        sources: entry.sources?.map(source => ({
          node: source.node?.tagName,
          currentRect: source.currentRect,
          previousRect: source.previousRect
        }))
      };
      
      this.addToDataBuffer('layout-shift', metrics);
    }
  }
  
  // 设置用户交互追踪
  setupUserInteractionTracking() {
    const interactionEvents = ['click', 'scroll', 'keydown', 'touchstart'];
    
    interactionEvents.forEach(eventType => {
      document.addEventListener(eventType, (event) => {
        this.trackUserInteraction(eventType, event);
      }, { passive: true });
    });
  }
  
  // 追踪用户交互
  trackUserInteraction(type, event) {
    const interaction = {
      type: 'user-interaction',
      timestamp: Date.now(),
      eventType: type,
      target: this.getElementSelector(event.target),
      coordinates: type === 'click' ? { x: event.clientX, y: event.clientY } : null,
      sessionTime: Date.now() - this.getSessionStartTime()
    };
    
    this.addToDataBuffer('interaction', interaction);
    
    // 更新用户会话数据
    this.updateUserSession(interaction);
  }
  
  // 设置网络监控
  setupNetworkMonitoring() {
    // 监听在线/离线状态
    window.addEventListener('online', () => {
      this.addToDataBuffer('network', {
        type: 'network-status',
        timestamp: Date.now(),
        status: 'online'
      });
    });
    
    window.addEventListener('offline', () => {
      this.addToDataBuffer('network', {
        type: 'network-status',
        timestamp: Date.now(),
        status: 'offline'
      });
    });
    
    // 监听连接信息
    if ('connection' in navigator) {
      const connection = navigator.connection;
      
      const collectConnectionInfo = () => {
        this.addToDataBuffer('network', {
          type: 'connection-info',
          timestamp: Date.now(),
          effectiveType: connection.effectiveType,
          downlink: connection.downlink,
          rtt: connection.rtt,
          saveData: connection.saveData
        });
      };
      
      connection.addEventListener('change', collectConnectionInfo);
      collectConnectionInfo(); // 初始收集
    }
  }
  
  // 设置内存监控
  setupMemoryMonitoring() {
    if ('memory' in performance) {
      setInterval(() => {
        const memInfo = performance.memory;
        this.addToDataBuffer('memory', {
          type: 'memory-usage',
          timestamp: Date.now(),
          usedJSHeapSize: memInfo.usedJSHeapSize,
          totalJSHeapSize: memInfo.totalJSHeapSize,
          jsHeapSizeLimit: memInfo.jsHeapSizeLimit,
          usagePercentage: (memInfo.usedJSHeapSize / memInfo.jsHeapSizeLimit) * 100
        });
      }, 30000); // 每30秒收集一次
    }
  }
  
  // 添加数据到缓冲区
  addToDataBuffer(category, data) {
    this.dataBuffer.push({
      category,
      data,
      timestamp: Date.now()
    });
    
    // 如果缓冲区满了,立即处理
    if (this.dataBuffer.length >= this.options.batchSize) {
      this.processDataBuffer();
    }
  }
  
  // 开始数据处理
  startDataProcessing() {
    // 定期处理数据缓冲区
    setInterval(() => {
      this.processDataBuffer();
    }, this.options.flushInterval);
    
    // 定期清理过期数据
    setInterval(() => {
      this.cleanupExpiredData();
    }, 3600000); // 每小时清理一次
  }
  
  // 处理数据缓冲区
  processDataBuffer() {
    if (this.dataBuffer.length === 0) return;
    
    const batch = this.dataBuffer.splice(0, this.options.batchSize);
    
    // 分析数据
    this.analyzeDataBatch(batch);
    
    // 存储到本地缓存
    this.storeDataBatch(batch);
    
    // 发送聚合数据到Sentry
    this.sendAggregatedData(batch);
  }
  
  // 分析数据批次
  analyzeDataBatch(batch) {
    const analysis = {
      performance: this.analyzePerformanceData(batch),
      userBehavior: this.analyzeUserBehaviorData(batch),
      errors: this.analyzeErrorData(batch),
      network: this.analyzeNetworkData(batch)
    };
    
    // 检测异常模式
    this.detectAnomalies(analysis);
    
    // 更新实时指标
    this.updateRealTimeMetrics(analysis);
  }
  
  // 分析性能数据
  analyzePerformanceData(batch) {
    const performanceData = batch.filter(item => 
      ['performance', 'resource', 'longtask', 'layout-shift'].includes(item.category)
    );
    
    if (performanceData.length === 0) return null;
    
    const analysis = {
      averageLoadTime: 0,
      slowestResources: [],
      longTaskCount: 0,
      layoutShiftScore: 0,
      performanceScore: 0
    };
    
    // 计算平均加载时间
    const navigationData = performanceData.filter(item => 
      item.category === 'performance' && item.data.type === 'navigation'
    );
    
    if (navigationData.length > 0) {
      analysis.averageLoadTime = navigationData.reduce(
        (sum, item) => sum + item.data.duration, 0
      ) / navigationData.length;
    }
    
    // 找出最慢的资源
    const resourceData = performanceData.filter(item => item.category === 'resource');
    analysis.slowestResources = resourceData
      .sort((a, b) => b.data.duration - a.data.duration)
      .slice(0, 5)
      .map(item => ({
        name: item.data.name,
        duration: item.data.duration,
        size: item.data.size
      }));
    
    // 计算长任务数量
    analysis.longTaskCount = performanceData.filter(
      item => item.category === 'longtask'
    ).length;
    
    // 计算布局偏移分数
    const layoutShiftData = performanceData.filter(
      item => item.category === 'layout-shift'
    );
    analysis.layoutShiftScore = layoutShiftData.reduce(
      (sum, item) => sum + item.data.value, 0
    );
    
    // 计算综合性能分数
    analysis.performanceScore = this.calculatePerformanceScore(analysis);
    
    return analysis;
  }
  
  // 分析用户行为数据
  analyzeUserBehaviorData(batch) {
    const behaviorData = batch.filter(item => item.category === 'interaction');
    
    if (behaviorData.length === 0) return null;
    
    const analysis = {
      totalInteractions: behaviorData.length,
      interactionTypes: {},
      averageSessionTime: 0,
      mostInteractedElements: {},
      userEngagement: 0
    };
    
    // 统计交互类型
    behaviorData.forEach(item => {
      const type = item.data.eventType;
      analysis.interactionTypes[type] = (analysis.interactionTypes[type] || 0) + 1;
    });
    
    // 统计最多交互的元素
    behaviorData.forEach(item => {
      const target = item.data.target;
      analysis.mostInteractedElements[target] = 
        (analysis.mostInteractedElements[target] || 0) + 1;
    });
    
    // 计算平均会话时间
    const sessionTimes = behaviorData.map(item => item.data.sessionTime);
    if (sessionTimes.length > 0) {
      analysis.averageSessionTime = sessionTimes.reduce((sum, time) => sum + time, 0) / sessionTimes.length;
    }
    
    // 计算用户参与度
    analysis.userEngagement = this.calculateUserEngagement(analysis);
    
    return analysis;
  }
  
  // 检测异常模式
  detectAnomalies(analysis) {
    const anomalies = [];
    
    // 检测性能异常
    if (analysis.performance) {
      if (analysis.performance.averageLoadTime > 5000) {
        anomalies.push({
          type: 'performance',
          severity: 'high',
          message: `Average load time is ${analysis.performance.averageLoadTime}ms`,
          data: analysis.performance
        });
      }
      
      if (analysis.performance.longTaskCount > 10) {
        anomalies.push({
          type: 'performance',
          severity: 'medium',
          message: `High number of long tasks: ${analysis.performance.longTaskCount}`,
          data: analysis.performance
        });
      }
      
      if (analysis.performance.layoutShiftScore > 0.25) {
        anomalies.push({
          type: 'performance',
          severity: 'medium',
          message: `High cumulative layout shift: ${analysis.performance.layoutShiftScore}`,
          data: analysis.performance
        });
      }
    }
    
    // 检测用户行为异常
    if (analysis.userBehavior) {
      if (analysis.userBehavior.userEngagement < 0.3) {
        anomalies.push({
          type: 'user-behavior',
          severity: 'medium',
          message: `Low user engagement: ${analysis.userBehavior.userEngagement}`,
          data: analysis.userBehavior
        });
      }
    }
    
    // 发送异常报告
    if (anomalies.length > 0) {
      this.reportAnomalies(anomalies);
    }
  }
  
  // 报告异常
  reportAnomalies(anomalies) {
    anomalies.forEach(anomaly => {
      Sentry.captureMessage(
        `Anomaly detected: ${anomaly.message}`,
        anomaly.severity === 'high' ? 'error' : 'warning',
        {
          tags: {
            category: 'anomaly-detection',
            type: anomaly.type,
            severity: anomaly.severity
          },
          extra: anomaly.data
        }
      );
    });
  }
  
  // 计算性能分数
  calculatePerformanceScore(analysis) {
    let score = 100;
    
    // 基于加载时间的扣分
    if (analysis.averageLoadTime > 3000) {
      score -= Math.min(30, (analysis.averageLoadTime - 3000) / 100);
    }
    
    // 基于长任务的扣分
    score -= Math.min(20, analysis.longTaskCount * 2);
    
    // 基于布局偏移的扣分
    score -= Math.min(25, analysis.layoutShiftScore * 100);
    
    return Math.max(0, Math.round(score));
  }
  
  // 计算用户参与度
  calculateUserEngagement(analysis) {
    let engagement = 0;
    
    // 基于交互数量
    engagement += Math.min(0.4, analysis.totalInteractions / 100);
    
    // 基于会话时间
    engagement += Math.min(0.3, analysis.averageSessionTime / 300000); // 5分钟为满分
    
    // 基于交互多样性
    const typeCount = Object.keys(analysis.interactionTypes).length;
    engagement += Math.min(0.3, typeCount / 4);
    
    return Math.round(engagement * 100) / 100;
  }
  
  // 获取元素选择器
  getElementSelector(element) {
    if (!element) return 'unknown';
    
    let selector = element.tagName.toLowerCase();
    
    if (element.id) {
      selector += `#${element.id}`;
    } else if (element.className) {
      selector += `.${element.className.split(' ').join('.')}`;
    }
    
    return selector;
  }
  
  // 获取资源类型
  getResourceType(url) {
    const extension = url.split('.').pop()?.toLowerCase();
    
    const typeMap = {
      'js': 'script',
      'css': 'stylesheet',
      'png': 'image',
      'jpg': 'image',
      'jpeg': 'image',
      'gif': 'image',
      'svg': 'image',
      'woff': 'font',
      'woff2': 'font',
      'ttf': 'font',
      'eot': 'font'
    };
    
    return typeMap[extension] || 'other';
  }
  
  // 获取导航来源
  getNavigationSource() {
    if (document.referrer) {
      try {
        const referrerDomain = new URL(document.referrer).hostname;
        const currentDomain = window.location.hostname;
        return referrerDomain === currentDomain ? 'internal' : 'external';
      } catch {
        return 'unknown';
      }
    }
    return 'direct';
  }
  
  // 获取用户细分
  getUserSegment() {
    // 这里可以根据业务逻辑实现用户细分
    const userId = localStorage.getItem('userId');
    if (!userId) return 'anonymous';
    
    // 示例:基于用户ID的简单细分
    const userType = localStorage.getItem('userType') || 'regular';
    return userType;
  }
  
  // 获取设备类型
  getDeviceType() {
    const userAgent = navigator.userAgent;
    
    if (/tablet|ipad|playbook|silk/i.test(userAgent)) {
      return 'tablet';
    }
    if (/mobile|iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(userAgent)) {
      return 'mobile';
    }
    return 'desktop';
  }
  
  // 获取当前会话ID
  getCurrentSessionId() {
    let sessionId = sessionStorage.getItem('sentrySessionId');
    if (!sessionId) {
      sessionId = 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
      sessionStorage.setItem('sentrySessionId', sessionId);
    }
    return sessionId;
  }
  
  // 获取用户旅程
  getUserJourney() {
    const journey = JSON.parse(localStorage.getItem('userJourney') || '[]');
    return journey.slice(-10); // 返回最近10个页面
  }
  
  // 获取性能上下文
  getPerformanceContext() {
    return {
      connectionType: navigator.connection?.effectiveType || 'unknown',
      deviceMemory: navigator.deviceMemory || 'unknown',
      hardwareConcurrency: navigator.hardwareConcurrency || 'unknown',
      cookieEnabled: navigator.cookieEnabled,
      language: navigator.language
    };
  }
  
  // 获取业务上下文
  getBusinessContext() {
    return {
      currentPage: window.location.pathname,
      referrer: document.referrer,
      timestamp: Date.now(),
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
      screenResolution: `${screen.width}x${screen.height}`,
      viewportSize: `${window.innerWidth}x${window.innerHeight}`
    };
  }
  
  // 分类错误
  categorizeError(event) {
    const errorType = event.exception?.values[0]?.type;
    const errorMessage = event.message || event.exception?.values[0]?.value || '';
    
    // 网络错误
    if (errorType === 'NetworkError' || errorMessage.includes('fetch')) {
      return 'network';
    }
    
    // 语法错误
    if (errorType === 'SyntaxError') {
      return 'syntax';
    }
    
    // 引用错误
    if (errorType === 'ReferenceError') {
      return 'reference';
    }
    
    // 类型错误
    if (errorType === 'TypeError') {
      return 'type';
    }
    
    // 权限错误
    if (errorType === 'SecurityError') {
      return 'security';
    }
    
    // 资源加载错误
    if (errorMessage.includes('Loading chunk') || errorMessage.includes('ChunkLoadError')) {
      return 'chunk-load';
    }
    
    return 'other';
  }
  
  // 计算影响级别
  calculateImpactLevel(event) {
    let score = 0;
    
    // 基于错误类型
    const errorCategory = this.categorizeError(event);
    const categoryScores = {
      'security': 10,
      'network': 7,
      'chunk-load': 6,
      'syntax': 8,
      'reference': 7,
      'type': 5,
      'other': 3
    };
    score += categoryScores[errorCategory] || 3;
    
    // 基于环境
    if (event.environment === 'production') {
      score += 3;
    }
    
    // 基于用户类型
    const userType = this.getUserType();
    if (userType === 'premium') {
      score += 2;
    }
    
    if (score >= 10) return 'critical';
    if (score >= 7) return 'high';
    if (score >= 4) return 'medium';
    return 'low';
  }
  
  // 获取用户类型
  getUserType() {
    return localStorage.getItem('userType') || 'regular';
  }
  
  // 获取活跃的功能标志
  getActiveFeatureFlags() {
    const flags = JSON.parse(localStorage.getItem('featureFlags') || '{}');
    return Object.keys(flags).filter(key => flags[key]).join(',');
  }
  
  // 缓存事件数据
  cacheEventData(event) {
    const key = `event_${Date.now()}`;
    this.metricsCache.set(key, {
      type: 'error',
      data: event,
      timestamp: Date.now()
    });
  }
  
  // 缓存用户行为
  cacheUserBehavior(breadcrumb) {
    const key = `behavior_${Date.now()}`;
    this.metricsCache.set(key, {
      type: 'behavior',
      data: breadcrumb,
      timestamp: Date.now()
    });
  }
  
  // 更新用户会话
  updateUserSession(interaction) {
    const userId = this.getUserId();
    const session = this.userSessions.get(userId) || {
      startTime: Date.now(),
      interactions: [],
      pageViews: 0,
      errors: 0
    };
    
    session.interactions.push(interaction);
    session.lastActivity = Date.now();
    
    this.userSessions.set(userId, session);
  }
  
  // 获取用户ID
  getUserId() {
    return localStorage.getItem('userId') || 'anonymous';
  }
  
  // 获取会话开始时间
  getSessionStartTime() {
    const userId = this.getUserId();
    const session = this.userSessions.get(userId);
    return session ? session.startTime : Date.now();
  }
  
  // 获取页面加载时间
  getPageLoadTime() {
    const navigation = performance.getEntriesByType('navigation')[0];
    return navigation ? navigation.loadEventEnd - navigation.loadEventStart : 0;
  }
  
  // 获取用户交互次数
  getUserInteractionCount() {
    const userId = this.getUserId();
    const session = this.userSessions.get(userId);
    return session ? session.interactions.length : 0;
  }
  
  // 获取First Paint
  getFirstPaint() {
    const paintEntries = performance.getEntriesByType('paint');
    const fpEntry = paintEntries.find(entry => entry.name === 'first-paint');
    return fpEntry ? fpEntry.startTime : 0;
  }
  
  // 获取First Contentful Paint
  getFirstContentfulPaint() {
    const paintEntries = performance.getEntriesByType('paint');
    const fcpEntry = paintEntries.find(entry => entry.name === 'first-contentful-paint');
    return fcpEntry ? fcpEntry.startTime : 0;
  }
  
  // 获取Largest Contentful Paint
  getLargestContentfulPaint() {
    return new Promise((resolve) => {
      const observer = new PerformanceObserver((list) => {
        const entries = list.getEntries();
        const lastEntry = entries[entries.length - 1];
        resolve(lastEntry ? lastEntry.startTime : 0);
        observer.disconnect();
      });
      observer.observe({ entryTypes: ['largest-contentful-paint'] });
      
      // 超时处理
      setTimeout(() => {
        observer.disconnect();
        resolve(0);
      }, 5000);
    });
  }
  
  // 获取First Input Delay
  getFirstInputDelay() {
    return new Promise((resolve) => {
      const observer = new PerformanceObserver((list) => {
        const entries = list.getEntries();
        const firstEntry = entries[0];
        resolve(firstEntry ? firstEntry.processingStart - firstEntry.startTime : 0);
        observer.disconnect();
      });
      observer.observe({ entryTypes: ['first-input'] });
      
      // 超时处理
      setTimeout(() => {
        observer.disconnect();
        resolve(0);
      }, 5000);
    });
  }
  
  // 获取Cumulative Layout Shift
  getCumulativeLayoutShift() {
    return new Promise((resolve) => {
      let clsValue = 0;
      const observer = new PerformanceObserver((list) => {
        for (const entry of list.getEntries()) {
          if (!entry.hadRecentInput) {
            clsValue += entry.value;
          }
        }
      });
      observer.observe({ entryTypes: ['layout-shift'] });
      
      // 在页面卸载时返回结果
      window.addEventListener('beforeunload', () => {
        observer.disconnect();
        resolve(clsValue);
      });
      
      // 超时处理
      setTimeout(() => {
        observer.disconnect();
        resolve(clsValue);
      }, 5000);
    });
  }
  
  // 获取Time to Interactive
  getTimeToInteractive() {
    // 简化的TTI计算
    const navigation = performance.getEntriesByType('navigation')[0];
    if (!navigation) return 0;
    
    return navigation.domContentLoadedEventEnd - navigation.fetchStart;
  }
  
  // 存储数据批次
  storeDataBatch(batch) {
    try {
      const existingData = JSON.parse(localStorage.getItem('sentryAnalyticsData') || '[]');
      const newData = [...existingData, ...batch];
      
      // 限制存储大小
      const maxItems = 1000;
      if (newData.length > maxItems) {
        newData.splice(0, newData.length - maxItems);
      }
      
      localStorage.setItem('sentryAnalyticsData', JSON.stringify(newData));
    } catch (error) {
      console.warn('Failed to store analytics data:', error);
    }
  }
  
  // 发送聚合数据
  sendAggregatedData(batch) {
    const aggregated = this.aggregateData(batch);
    
    if (Object.keys(aggregated).length > 0) {
      Sentry.addBreadcrumb({
        category: 'analytics',
        message: 'Aggregated data collected',
        level: 'info',
        data: aggregated
      });
    }
  }
  
  // 聚合数据
  aggregateData(batch) {
    const aggregated = {
      performance: {},
      interactions: {},
      network: {},
      memory: {}
    };
    
    batch.forEach(item => {
      switch (item.category) {
        case 'performance':
          this.aggregatePerformanceData(aggregated.performance, item.data);
          break;
        case 'interaction':
          this.aggregateInteractionData(aggregated.interactions, item.data);
          break;
        case 'network':
          this.aggregateNetworkData(aggregated.network, item.data);
          break;
        case 'memory':
          this.aggregateMemoryData(aggregated.memory, item.data);
          break;
      }
    });
    
    return aggregated;
  }
  
  // 聚合性能数据
  aggregatePerformanceData(target, data) {
    if (data.type === 'navigation') {
      target.navigationCount = (target.navigationCount || 0) + 1;
      target.totalDuration = (target.totalDuration || 0) + data.duration;
      target.averageDuration = target.totalDuration / target.navigationCount;
    }
  }
  
  // 聚合交互数据
  aggregateInteractionData(target, data) {
    target.totalInteractions = (target.totalInteractions || 0) + 1;
    target.byType = target.byType || {};
    target.byType[data.eventType] = (target.byType[data.eventType] || 0) + 1;
  }
  
  // 聚合网络数据
  aggregateNetworkData(target, data) {
    if (data.type === 'connection-info') {
      target.connectionType = data.effectiveType;
      target.downlink = data.downlink;
      target.rtt = data.rtt;
    }
  }
  
  // 聚合内存数据
  aggregateMemoryData(target, data) {
    if (data.type === 'memory-usage') {
      target.currentUsage = data.usagePercentage;
      target.maxUsage = Math.max(target.maxUsage || 0, data.usagePercentage);
    }
  }
  
  // 清理过期数据
  cleanupExpiredData() {
    const cutoffTime = Date.now() - (this.options.dataRetentionDays * 24 * 60 * 60 * 1000);
    
    // 清理内存缓存
    this.metricsCache.forEach((value, key) => {
      if (value.timestamp < cutoffTime) {
        this.metricsCache.delete(key);
      }
    });
    
    // 清理本地存储
    try {
      const storedData = JSON.parse(localStorage.getItem('sentryAnalyticsData') || '[]');
      const filteredData = storedData.filter(item => item.timestamp > cutoffTime);
      localStorage.setItem('sentryAnalyticsData', JSON.stringify(filteredData));
    } catch (error) {
      console.warn('Failed to cleanup stored data:', error);
    }
  }
  
  // 获取分析数据
  getAnalyticsData(timeRange = '24h') {
    const timeRanges = {
      '1h': 3600000,
      '24h': 86400000,
      '7d': 604800000,
      '30d': 2592000000
    };
    
    const cutoffTime = Date.now() - (timeRanges[timeRange] || timeRanges['24h']);
    
    try {
      const storedData = JSON.parse(localStorage.getItem('sentryAnalyticsData') || '[]');
      return storedData.filter(item => item.timestamp > cutoffTime);
    } catch (error) {
      console.warn('Failed to get analytics data:', error);
      return [];
    }
  }
  
  // 获取实时指标
  getRealTimeMetrics() {
    const userId = this.getUserId();
    const session = this.userSessions.get(userId);
    
    return {
      sessionDuration: session ? Date.now() - session.startTime : 0,
      interactionCount: session ? session.interactions.length : 0,
      pageViews: session ? session.pageViews : 0,
      errorCount: session ? session.errors : 0,
      memoryUsage: this.getCurrentMemoryUsage(),
      connectionType: navigator.connection?.effectiveType || 'unknown'
    };
  }
  
  // 获取当前内存使用
  getCurrentMemoryUsage() {
    if ('memory' in performance) {
      const memInfo = performance.memory;
      return {
        used: memInfo.usedJSHeapSize,
        total: memInfo.totalJSHeapSize,
        limit: memInfo.jsHeapSizeLimit,
        percentage: (memInfo.usedJSHeapSize / memInfo.jsHeapSizeLimit) * 100
      };
    }
    return null;
  }
}

// 创建全局数据收集系统实例
export const dataCollectionSystem = new DataCollectionSystem();

// 导出便捷方法
export const getAnalyticsData = (timeRange) => dataCollectionSystem.getAnalyticsData(timeRange);
export const getRealTimeMetrics = () => dataCollectionSystem.getRealTimeMetrics();

1.2 数据分析引擎

// dataAnalysisEngine.js
import * as Sentry from '@sentry/browser';

// 数据分析引擎
export class DataAnalysisEngine {
  constructor(options = {}) {
    this.options = {
      enableTrendAnalysis: true,
      enableAnomalyDetection: true,
      enablePredictiveAnalysis: false,
      analysisInterval: 300000, // 5分钟
      trendWindow: 86400000, // 24小时
      anomalyThreshold: 2, // 标准差倍数
      ...options
    };
    
    this.analysisCache = new Map();
    this.trendData = new Map();
    this.baselineMetrics = new Map();
    
    this.startAnalysisEngine();
  }
  
  startAnalysisEngine() {
    // 定期执行分析
    setInterval(() => {
      this.performAnalysis();
    }, this.options.analysisInterval);
    
    // 初始化基线指标
    this.initializeBaselines();
  }
  
  // 执行分析
  async performAnalysis() {
    try {
      const data = this.getAnalysisData();
      
      if (data.length === 0) return;
      
      const analysis = {
        timestamp: Date.now(),
        errorAnalysis: await this.analyzeErrors(data),
        performanceAnalysis: await this.analyzePerformance(data),
        userBehaviorAnalysis: await this.analyzeUserBehavior(data),
        trendAnalysis: this.options.enableTrendAnalysis ? await this.analyzeTrends(data) : null,
        anomalyAnalysis: this.options.enableAnomalyDetection ? await this.detectAnomalies(data) : null
      };
      
      // 缓存分析结果
      this.cacheAnalysisResult(analysis);
      
      // 发送分析结果到Sentry
      this.sendAnalysisToSentry(analysis);
      
      // 触发告警
      this.checkAlerts(analysis);
      
    } catch (error) {
      console.error('Analysis failed:', error);
      Sentry.captureException(error, {
        tags: {
          category: 'data-analysis',
          operation: 'perform-analysis'
        }
      });
    }
  }
  
  // 获取分析数据
  getAnalysisData() {
    try {
      const storedData = JSON.parse(localStorage.getItem('sentryAnalyticsData') || '[]');
      const cutoffTime = Date.now() - this.options.trendWindow;
      return storedData.filter(item => item.timestamp > cutoffTime);
    } catch (error) {
      console.warn('Failed to get analysis data:', error);
      return [];
    }
  }
  
  // 分析错误
  async analyzeErrors(data) {
    const errorData = data.filter(item => item.category === 'error');
    
    if (errorData.length === 0) {
      return {
        totalErrors: 0,
        errorRate: 0,
        topErrors: [],
        errorTrends: {},
        impactAnalysis: {}
      };
    }
    
    const analysis = {
      totalErrors: errorData.length,
      errorRate: this.calculateErrorRate(errorData, data),
      topErrors: this.getTopErrors(errorData),
      errorTrends: this.getErrorTrends(errorData),
      impactAnalysis: this.analyzeErrorImpact(errorData),
      categoryDistribution: this.getErrorCategoryDistribution(errorData),
      severityDistribution: this.getErrorSeverityDistribution(errorData),
      environmentDistribution: this.getErrorEnvironmentDistribution(errorData)
    };
    
    return analysis;
  }
  
  // 计算错误率
  calculateErrorRate(errorData, allData) {
    const totalEvents = allData.length;
    return totalEvents > 0 ? (errorData.length / totalEvents) * 100 : 0;
  }
  
  // 获取顶级错误
  getTopErrors(errorData) {
    const errorCounts = new Map();
    
    errorData.forEach(item => {
      const errorKey = this.getErrorKey(item.data);
      const count = errorCounts.get(errorKey) || 0;
      errorCounts.set(errorKey, count + 1);
    });
    
    return Array.from(errorCounts.entries())
      .sort((a, b) => b[1] - a[1])
      .slice(0, 10)
      .map(([error, count]) => ({ error, count }));
  }
  
  // 获取错误键
  getErrorKey(errorData) {
    const errorType = errorData.exception?.values[0]?.type || 'Unknown';
    const errorMessage = errorData.message || errorData.exception?.values[0]?.value || 'Unknown';
    return `${errorType}: ${errorMessage.substring(0, 100)}`;
  }
  
  // 获取错误趋势
  getErrorTrends(errorData) {
    const hourlyTrends = new Map();
    const now = Date.now();
    
    // 初始化24小时的数据
    for (let i = 23; i >= 0; i--) {
      const hour = new Date(now - i * 3600000).getHours();
      hourlyTrends.set(hour, 0);
    }
    
    // 统计每小时的错误数
    errorData.forEach(item => {
      const hour = new Date(item.timestamp).getHours();
      const count = hourlyTrends.get(hour) || 0;
      hourlyTrends.set(hour, count + 1);
    });
    
    return Object.fromEntries(hourlyTrends);
  }
  
  // 分析错误影响
  analyzeErrorImpact(errorData) {
    const impactLevels = {
      critical: 0,
      high: 0,
      medium: 0,
      low: 0
    };
    
    const affectedUsers = new Set();
    const affectedPages = new Set();
    
    errorData.forEach(item => {
      const impact = item.data.tags?.impactLevel || 'low';
      impactLevels[impact] = (impactLevels[impact] || 0) + 1;
      
      if (item.data.user?.id) {
        affectedUsers.add(item.data.user.id);
      }
      
      if (item.data.request?.url) {
        affectedPages.add(item.data.request.url);
      }
    });
    
    return {
      impactLevels,
      affectedUsers: affectedUsers.size,
      affectedPages: affectedPages.size,
      totalImpactScore: this.calculateTotalImpactScore(impactLevels)
    };
  }
  
  // 计算总影响分数
  calculateTotalImpactScore(impactLevels) {
    const weights = { critical: 10, high: 7, medium: 4, low: 1 };
    return Object.entries(impactLevels).reduce(
      (total, [level, count]) => total + (count * (weights[level] || 1)), 0
    );
  }
  
  // 获取错误分类分布
  getErrorCategoryDistribution(errorData) {
    const distribution = {};
    
    errorData.forEach(item => {
      const category = item.data.tags?.errorCategory || 'other';
      distribution[category] = (distribution[category] || 0) + 1;
    });
    
    return distribution;
  }
  
  // 获取错误严重性分布
  getErrorSeverityDistribution(errorData) {
    const distribution = {};
    
    errorData.forEach(item => {
      const severity = item.data.level || 'error';
      distribution[severity] = (distribution[severity] || 0) + 1;
    });
    
    return distribution;
  }
  
  // 获取错误环境分布
  getErrorEnvironmentDistribution(errorData) {
    const distribution = {};
    
    errorData.forEach(item => {
      const environment = item.data.environment || 'unknown';
      distribution[environment] = (distribution[environment] || 0) + 1;
    });
    
    return distribution;
  }
  
  // 分析性能
  async analyzePerformance(data) {
    const performanceData = data.filter(item => 
      ['performance', 'resource', 'longtask', 'layout-shift', 'memory'].includes(item.category)
    );
    
    if (performanceData.length === 0) {
      return {
        overallScore: 0,
        coreWebVitals: {},
        resourceAnalysis: {},
        memoryAnalysis: {},
        performanceTrends: {}
      };
    }
    
    const analysis = {
      overallScore: this.calculateOverallPerformanceScore(performanceData),
      coreWebVitals: this.analyzeCoreWebVitals(performanceData),
      resourceAnalysis: this.analyzeResources(performanceData),
      memoryAnalysis: this.analyzeMemoryUsage(performanceData),
      performanceTrends: this.getPerformanceTrends(performanceData),
      longTaskAnalysis: this.analyzeLongTasks(performanceData),
      layoutShiftAnalysis: this.analyzeLayoutShifts(performanceData)
    };
    
    return analysis;
  }
  
  // 计算整体性能分数
  calculateOverallPerformanceScore(performanceData) {
    const navigationData = performanceData.filter(
      item => item.category === 'performance' && item.data.type === 'navigation'
    );
    
    if (navigationData.length === 0) return 0;
    
    let totalScore = 0;
    let scoreCount = 0;
    
    navigationData.forEach(item => {
      const data = item.data;
      let score = 100;
      
      // FCP评分 (0-2.5s: 100分, 2.5-4s: 50分, >4s: 0分)
      if (data.firstContentfulPaint > 4000) {
        score -= 30;
      } else if (data.firstContentfulPaint > 2500) {
        score -= 15;
      }
      
      // LCP评分 (0-2.5s: 100分, 2.5-4s: 50分, >4s: 0分)
      if (data.largestContentfulPaint > 4000) {
        score -= 30;
      } else if (data.largestContentfulPaint > 2500) {
        score -= 15;
      }
      
      // FID评分 (0-100ms: 100分, 100-300ms: 50分, >300ms: 0分)
      if (data.firstInputDelay > 300) {
        score -= 25;
      } else if (data.firstInputDelay > 100) {
        score -= 12;
      }
      
      // CLS评分 (0-0.1: 100分, 0.1-0.25: 50分, >0.25: 0分)
      if (data.cumulativeLayoutShift > 0.25) {
        score -= 15;
      } else if (data.cumulativeLayoutShift > 0.1) {
        score -= 7;
      }
      
      totalScore += Math.max(0, score);
      scoreCount++;
    });
    
    return scoreCount > 0 ? Math.round(totalScore / scoreCount) : 0;
  }
  
  // 分析Core Web Vitals
  analyzeCoreWebVitals(performanceData) {
    const navigationData = performanceData.filter(
      item => item.category === 'performance' && item.data.type === 'navigation'
    );
    
    if (navigationData.length === 0) {
      return {
        lcp: { average: 0, p75: 0, p95: 0, status: 'unknown' },
        fid: { average: 0, p75: 0, p95: 0, status: 'unknown' },
        cls: { average: 0, p75: 0, p95: 0, status: 'unknown' },
        fcp: { average: 0, p75: 0, p95: 0, status: 'unknown' }
      };
    }
    
    const lcpValues = navigationData.map(item => item.data.largestContentfulPaint).filter(v => v > 0);
    const fidValues = navigationData.map(item => item.data.firstInputDelay).filter(v => v > 0);
    const clsValues = navigationData.map(item => item.data.cumulativeLayoutShift).filter(v => v >= 0);
    const fcpValues = navigationData.map(item => item.data.firstContentfulPaint).filter(v => v > 0);
    
    return {
      lcp: this.calculateMetricStats(lcpValues, [2500, 4000]),
      fid: this.calculateMetricStats(fidValues, [100, 300]),
      cls: this.calculateMetricStats(clsValues, [0.1, 0.25]),
      fcp: this.calculateMetricStats(fcpValues, [1800, 3000])
    };
  }
  
  // 计算指标统计
  calculateMetricStats(values, thresholds) {
    if (values.length === 0) {
      return { average: 0, p75: 0, p95: 0, status: 'unknown' };
    }
    
    const sorted = values.sort((a, b) => a - b);
    const average = values.reduce((sum, val) => sum + val, 0) / values.length;
    const p75 = this.getPercentile(sorted, 75);
    const p95 = this.getPercentile(sorted, 95);
    
    let status = 'good';
    if (p75 > thresholds[1]) {
      status = 'poor';
    } else if (p75 > thresholds[0]) {
      status = 'needs-improvement';
    }
    
    return {
      average: Math.round(average),
      p75: Math.round(p75),
      p95: Math.round(p95),
      status
    };
  }
  
  // 获取百分位数
  getPercentile(sortedArray, percentile) {
    const index = (percentile / 100) * (sortedArray.length - 1);
    const lower = Math.floor(index);
    const upper = Math.ceil(index);
    const weight = index % 1;
    
    if (upper >= sortedArray.length) return sortedArray[sortedArray.length - 1];
    
    return sortedArray[lower] * (1 - weight) + sortedArray[upper] * weight;
  }
  
  // 分析资源
  analyzeResources(performanceData) {
    const resourceData = performanceData.filter(item => item.category === 'resource');
    
    if (resourceData.length === 0) {
      return {
        totalResources: 0,
        totalSize: 0,
        averageLoadTime: 0,
        slowestResources: [],
        resourceTypes: {}
      };
    }
    
    const totalSize = resourceData.reduce((sum, item) => sum + (item.data.size || 0), 0);
    const totalDuration = resourceData.reduce((sum, item) => sum + item.data.duration, 0);
    const averageLoadTime = totalDuration / resourceData.length;
    
    // 按类型分组
    const resourceTypes = {};
    resourceData.forEach(item => {
      const type = item.data.resourceType || 'other';
      if (!resourceTypes[type]) {
        resourceTypes[type] = { count: 0, totalSize: 0, totalDuration: 0 };
      }
      resourceTypes[type].count++;
      resourceTypes[type].totalSize += item.data.size || 0;
      resourceTypes[type].totalDuration += item.data.duration;
    });
    
    // 计算每种类型的平均值
    Object.keys(resourceTypes).forEach(type => {
      const typeData = resourceTypes[type];
      typeData.averageSize = typeData.totalSize / typeData.count;
      typeData.averageDuration = typeData.totalDuration / typeData.count;
    });
    
    // 找出最慢的资源
    const slowestResources = resourceData
      .sort((a, b) => b.data.duration - a.data.duration)
      .slice(0, 5)
      .map(item => ({
        name: item.data.name,
        duration: item.data.duration,
        size: item.data.size,
        type: item.data.resourceType
      }));
    
    return {
      totalResources: resourceData.length,
      totalSize,
      averageLoadTime,
      slowestResources,
      resourceTypes
    };
  }
  
  // 分析内存使用
  analyzeMemoryUsage(performanceData) {
    const memoryData = performanceData.filter(item => item.category === 'memory');
    
    if (memoryData.length === 0) {
      return {
        currentUsage: 0,
        maxUsage: 0,
        averageUsage: 0,
        trend: 'stable'
      };
    }
    
    const usageValues = memoryData.map(item => item.data.usagePercentage);
    const currentUsage = usageValues[usageValues.length - 1];
    const maxUsage = Math.max(...usageValues);
    const averageUsage = usageValues.reduce((sum, val) => sum + val, 0) / usageValues.length;
    
    // 计算趋势
    let trend = 'stable';
    if (usageValues.length > 1) {
      const recent = usageValues.slice(-5);
      const older = usageValues.slice(-10, -5);
      
      if (recent.length > 0 && older.length > 0) {
        const recentAvg = recent.reduce((sum, val) => sum + val, 0) / recent.length;
        const olderAvg = older.reduce((sum, val) => sum + val, 0) / older.length;
        
        if (recentAvg > olderAvg + 5) {
          trend = 'increasing';
        } else if (recentAvg < olderAvg - 5) {
          trend = 'decreasing';
        }
      }
    }
    
    return {
      currentUsage: Math.round(currentUsage),
      maxUsage: Math.round(maxUsage),
      averageUsage: Math.round(averageUsage),
      trend
    };
  }
  
  // 获取性能趋势
  getPerformanceTrends(performanceData) {
    const hourlyTrends = new Map();
    const now = Date.now();
    
    // 初始化24小时的数据
    for (let i = 23; i >= 0; i--) {
      const hour = new Date(now - i * 3600000).getHours();
      hourlyTrends.set(hour, {
        loadTime: [],
        resourceCount: 0,
        longTasks: 0,
        layoutShifts: 0
      });
    }
    
    // 统计每小时的性能数据
    performanceData.forEach(item => {
      const hour = new Date(item.timestamp).getHours();
      const hourData = hourlyTrends.get(hour);
      
      if (!hourData) return;
      
      switch (item.category) {
        case 'performance':
          if (item.data.type === 'navigation') {
            hourData.loadTime.push(item.data.duration);
          }
          break;
        case 'resource':
          hourData.resourceCount++;
          break;
        case 'longtask':
          hourData.longTasks++;
          break;
        case 'layout-shift':
          hourData.layoutShifts++;
          break;
      }
    });
    
    // 计算每小时的平均值
    const trends = {};
    hourlyTrends.forEach((data, hour) => {
      trends[hour] = {
        averageLoadTime: data.loadTime.length > 0 
          ? data.loadTime.reduce((sum, time) => sum + time, 0) / data.loadTime.length 
          : 0,
        resourceCount: data.resourceCount,
        longTasks: data.longTasks,
        layoutShifts: data.layoutShifts
      };
    });
    
    return trends;
  }
  
  // 分析长任务
  analyzeLongTasks(performanceData) {
    const longTaskData = performanceData.filter(item => item.category === 'longtask');
    
    if (longTaskData.length === 0) {
      return {
        totalCount: 0,
        averageDuration: 0,
        maxDuration: 0,
        impactScore: 0
      };
    }
    
    const durations = longTaskData.map(item => item.data.duration);
    const totalDuration = durations.reduce((sum, duration) => sum + duration, 0);
    const averageDuration = totalDuration / durations.length;
    const maxDuration = Math.max(...durations);
    
    // 计算影响分数 (基于数量和持续时间)
    const impactScore = Math.min(100, (longTaskData.length * 5) + (averageDuration / 10));
    
    return {
      totalCount: longTaskData.length,
      averageDuration: Math.round(averageDuration),
      maxDuration: Math.round(maxDuration),
      impactScore: Math.round(impactScore)
    };
  }
  
  // 分析布局偏移
  analyzeLayoutShifts(performanceData) {
    const layoutShiftData = performanceData.filter(item => item.category === 'layout-shift');
    
    if (layoutShiftData.length === 0) {
      return {
        totalShifts: 0,
        cumulativeScore: 0,
        averageShift: 0,
        impactLevel: 'good'
      };
    }
    
    const shiftValues = layoutShiftData.map(item => item.data.value);
    const cumulativeScore = shiftValues.reduce((sum, value) => sum + value, 0);
    const averageShift = cumulativeScore / shiftValues.length;
    
    // 确定影响级别
    let impactLevel = 'good';
    if (cumulativeScore > 0.25) {
      impactLevel = 'poor';
    } else if (cumulativeScore > 0.1) {
      impactLevel = 'needs-improvement';
    }
    
    return {
      totalShifts: layoutShiftData.length,
      cumulativeScore: Math.round(cumulativeScore * 1000) / 1000,
      averageShift: Math.round(averageShift * 1000) / 1000,
      impactLevel
    };
  }
  
  // 分析用户行为
  async analyzeUserBehavior(data) {
    const behaviorData = data.filter(item => item.category === 'interaction');
    
    if (behaviorData.length === 0) {
      return {
        totalInteractions: 0,
        engagementScore: 0,
        sessionAnalysis: {},
        interactionPatterns: {},
        userJourney: []
      };
    }
    
    const analysis = {
      totalInteractions: behaviorData.length,
      engagementScore: this.calculateEngagementScore(behaviorData),
      sessionAnalysis: this.analyzeUserSessions(behaviorData),
      interactionPatterns: this.analyzeInteractionPatterns(behaviorData),
      userJourney: this.analyzeUserJourney(behaviorData),
      deviceAnalysis: this.analyzeDeviceUsage(behaviorData),
      timeAnalysis: this.analyzeTimePatterns(behaviorData)
    };
    
    return analysis;
  }
  
  // 计算参与度分数
  calculateEngagementScore(behaviorData) {
    let score = 0;
    
    // 基于交互数量 (最多40分)
    const interactionScore = Math.min(40, behaviorData.length * 2);
    score += interactionScore;
    
    // 基于交互多样性 (最多30分)
    const interactionTypes = new Set(behaviorData.map(item => item.data.eventType));
    const diversityScore = Math.min(30, interactionTypes.size * 7.5);
    score += diversityScore;
    
    // 基于会话时长 (最多30分)
    const sessionTimes = behaviorData.map(item => item.data.sessionTime);
    const maxSessionTime = Math.max(...sessionTimes);
    const timeScore = Math.min(30, maxSessionTime / 10000); // 10秒为1分
    score += timeScore;
    
    return Math.round(score);
  }
  
  // 分析用户会话
  analyzeUserSessions(behaviorData) {
    const sessions = new Map();
    
    behaviorData.forEach(item => {
      const sessionId = item.data.sessionId || 'default';
      if (!sessions.has(sessionId)) {
        sessions.set(sessionId, {
          interactions: [],
          startTime: item.timestamp,
          endTime: item.timestamp
        });
      }
      
      const session = sessions.get(sessionId);
      session.interactions.push(item);
      session.endTime = Math.max(session.endTime, item.timestamp);
    });
    
    const sessionAnalysis = {
      totalSessions: sessions.size,
      averageSessionDuration: 0,
      averageInteractionsPerSession: 0,
      longestSession: 0,
      shortestSession: Infinity
    };
    
    let totalDuration = 0;
    let totalInteractions = 0;
    
    sessions.forEach(session => {
      const duration = session.endTime - session.startTime;
      totalDuration += duration;
      totalInteractions += session.interactions.length;
      
      sessionAnalysis.longestSession = Math.max(sessionAnalysis.longestSession, duration);
      sessionAnalysis.shortestSession = Math.min(sessionAnalysis.shortestSession, duration);
    });
    
    sessionAnalysis.averageSessionDuration = Math.round(totalDuration / sessions.size);
    sessionAnalysis.averageInteractionsPerSession = Math.round(totalInteractions / sessions.size);
    
    if (sessionAnalysis.shortestSession === Infinity) {
      sessionAnalysis.shortestSession = 0;
    }
    
    return sessionAnalysis;
  }
  
  // 分析交互模式
  analyzeInteractionPatterns(behaviorData) {
    const patterns = {
      byType: {},
      byTarget: {},
      byTime: {},
      sequences: []
    };
    
    // 按类型统计
    behaviorData.forEach(item => {
      const type = item.data.eventType;
      patterns.byType[type] = (patterns.byType[type] || 0) + 1;
    });
    
    // 按目标元素统计
    behaviorData.forEach(item => {
      const target = item.data.target;
      patterns.byTarget[target] = (patterns.byTarget[target] || 0) + 1;
    });
    
    // 按时间段统计
    behaviorData.forEach(item => {
      const hour = new Date(item.timestamp).getHours();
      patterns.byTime[hour] = (patterns.byTime[hour] || 0) + 1;
    });
    
    // 分析交互序列
    const sortedData = behaviorData.sort((a, b) => a.timestamp - b.timestamp);
    for (let i = 0; i < sortedData.length - 1; i++) {
      const current = sortedData[i];
      const next = sortedData[i + 1];
      const timeDiff = next.timestamp - current.timestamp;
      
      if (timeDiff < 5000) { // 5秒内的连续交互
        patterns.sequences.push({
          from: current.data.eventType,
          to: next.data.eventType,
          interval: timeDiff
        });
      }
    }
    
    return patterns;
  }
  
  // 分析用户旅程
  analyzeUserJourney(behaviorData) {
    const journey = [];
    const sortedData = behaviorData.sort((a, b) => a.timestamp - b.timestamp);
    
    let currentPage = null;
    let pageStartTime = null;
    
    sortedData.forEach(item => {
      const page = this.extractPageFromInteraction(item);
      
      if (page !== currentPage) {
        if (currentPage) {
          journey.push({
            page: currentPage,
            startTime: pageStartTime,
            endTime: item.timestamp,
            duration: item.timestamp - pageStartTime,
            interactions: sortedData.filter(d => 
              d.timestamp >= pageStartTime && 
              d.timestamp < item.timestamp &&
              this.extractPageFromInteraction(d) === currentPage
            ).length
          });
        }
        
        currentPage = page;
        pageStartTime = item.timestamp;
      }
    });
    
    // 添加最后一个页面
    if (currentPage && pageStartTime) {
      const lastTimestamp = sortedData[sortedData.length - 1].timestamp;
      journey.push({
        page: currentPage,
        startTime: pageStartTime,
        endTime: lastTimestamp,
        duration: lastTimestamp - pageStartTime,
        interactions: sortedData.filter(d => 
          d.timestamp >= pageStartTime &&
          this.extractPageFromInteraction(d) === currentPage
        ).length
      });
    }
    
    return journey;
  }
  
  // 从交互中提取页面信息
  extractPageFromInteraction(interaction) {
    // 这里可以根据实际情况实现页面提取逻辑
    return interaction.data.page || window.location.pathname;
  }
  
  // 分析设备使用情况
  analyzeDeviceUsage(behaviorData) {
    const deviceTypes = {};
    const browsers = {};
    const screenSizes = {};
    
    behaviorData.forEach(item => {
      const deviceType = item.data.deviceType || 'unknown';
      const browser = item.data.browser || 'unknown';
      const screenSize = item.data.screenSize || 'unknown';
      
      deviceTypes[deviceType] = (deviceTypes[deviceType] || 0) + 1;
      browsers[browser] = (browsers[browser] || 0) + 1;
      screenSizes[screenSize] = (screenSizes[screenSize] || 0) + 1;
    });
    
    return {
      deviceTypes,
      browsers,
      screenSizes
    };
  }
  
  // 分析时间模式
  analyzeTimePatterns(behaviorData) {
    const hourlyActivity = new Array(24).fill(0);
    const dailyActivity = {};
    
    behaviorData.forEach(item => {
      const date = new Date(item.timestamp);
      const hour = date.getHours();
      const day = date.toDateString();
      
      hourlyActivity[hour]++;
      dailyActivity[day] = (dailyActivity[day] || 0) + 1;
    });
    
    // 找出最活跃的时间段
    const peakHour = hourlyActivity.indexOf(Math.max(...hourlyActivity));
    const peakDay = Object.keys(dailyActivity).reduce((a, b) => 
      dailyActivity[a] > dailyActivity[b] ? a : b
    );
    
    return {
       hourlyActivity,
       dailyActivity,
       peakHour,
       peakDay,
       totalActiveDays: Object.keys(dailyActivity).length
     };
   }
}

// 使用示例
const dataAnalyzer = new SentryDataAnalyzer();

// 启动数据收集
dataAnalyzer.startDataCollection();

// 定期执行分析
setInterval(async () => {
  const analysis = await dataAnalyzer.performAnalysis();
  console.log('分析结果:', analysis);
}, 60000); // 每分钟分析一次

3. 智能化监控仪表板实现

3.1 实时监控仪表板组件

// 智能监控仪表板
class IntelligentMonitoringDashboard {
  constructor(containerId, options = {}) {
    this.container = document.getElementById(containerId);
    this.options = {
      refreshInterval: 30000, // 30秒刷新间隔
      theme: 'light',
      autoResize: true,
      ...options
    };
    
    this.charts = new Map();
    this.widgets = new Map();
    this.dataAnalyzer = new SentryDataAnalyzer();
    this.alertManager = new AlertManager();
    
    this.init();
  }
  
  // 初始化仪表板
  async init() {
    this.createLayout();
    this.setupEventListeners();
    await this.loadInitialData();
    this.startRealTimeUpdates();
    
    // 启用自动调整大小
    if (this.options.autoResize) {
      window.addEventListener('resize', this.handleResize.bind(this));
    }
  }
  
  // 创建布局
  createLayout() {
    this.container.innerHTML = `
      <div class="dashboard-header">
        <h1>智能监控仪表板</h1>
        <div class="dashboard-controls">
          <select id="timeRange">
            <option value="1h">最近1小时</option>
            <option value="6h">最近6小时</option>
            <option value="24h" selected>最近24小时</option>
            <option value="7d">最近7天</option>
          </select>
          <button id="refreshBtn">刷新</button>
          <button id="exportBtn">导出</button>
        </div>
      </div>
      
      <div class="dashboard-grid">
        <!-- 关键指标卡片 -->
        <div class="metrics-row">
          <div class="metric-card" id="errorRate">
            <h3>错误率</h3>
            <div class="metric-value">-</div>
            <div class="metric-trend">-</div>
          </div>
          <div class="metric-card" id="performanceScore">
            <h3>性能评分</h3>
            <div class="metric-value">-</div>
            <div class="metric-trend">-</div>
          </div>
          <div class="metric-card" id="userSatisfaction">
            <h3>用户满意度</h3>
            <div class="metric-value">-</div>
            <div class="metric-trend">-</div>
          </div>
          <div class="metric-card" id="activeUsers">
            <h3>活跃用户</h3>
            <div class="metric-value">-</div>
            <div class="metric-trend">-</div>
          </div>
        </div>
        
        <!-- 图表区域 -->
        <div class="charts-row">
          <div class="chart-container">
            <h3>错误趋势</h3>
            <canvas id="errorTrendChart"></canvas>
          </div>
          <div class="chart-container">
            <h3>性能指标</h3>
            <canvas id="performanceChart"></canvas>
          </div>
        </div>
        
        <div class="charts-row">
          <div class="chart-container">
            <h3>用户行为热图</h3>
            <div id="userHeatmap"></div>
          </div>
          <div class="chart-container">
            <h3>实时告警</h3>
            <div id="alertsList"></div>
          </div>
        </div>
        
        <!-- 详细分析区域 -->
        <div class="analysis-row">
          <div class="analysis-panel">
            <h3>智能分析建议</h3>
            <div id="intelligentInsights"></div>
          </div>
          <div class="analysis-panel">
            <h3>性能瓶颈识别</h3>
            <div id="bottleneckAnalysis"></div>
          </div>
        </div>
      </div>
    `;
    
    this.addStyles();
  }
  
  // 添加样式
  addStyles() {
    const styles = `
      <style>
        .dashboard-header {
          display: flex;
          justify-content: space-between;
          align-items: center;
          padding: 20px;
          background: #f8f9fa;
          border-bottom: 1px solid #e9ecef;
        }
        
        .dashboard-controls {
          display: flex;
          gap: 10px;
        }
        
        .dashboard-controls select,
        .dashboard-controls button {
          padding: 8px 16px;
          border: 1px solid #ddd;
          border-radius: 4px;
          background: white;
          cursor: pointer;
        }
        
        .dashboard-grid {
          padding: 20px;
        }
        
        .metrics-row {
          display: grid;
          grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
          gap: 20px;
          margin-bottom: 30px;
        }
        
        .metric-card {
          background: white;
          padding: 20px;
          border-radius: 8px;
          box-shadow: 0 2px 4px rgba(0,0,0,0.1);
          text-align: center;
        }
        
        .metric-card h3 {
          margin: 0 0 10px 0;
          color: #666;
          font-size: 14px;
          text-transform: uppercase;
        }
        
        .metric-value {
          font-size: 32px;
          font-weight: bold;
          color: #333;
          margin-bottom: 5px;
        }
        
        .metric-trend {
          font-size: 12px;
          color: #666;
        }
        
        .metric-trend.positive {
          color: #28a745;
        }
        
        .metric-trend.negative {
          color: #dc3545;
        }
        
        .charts-row {
          display: grid;
          grid-template-columns: 1fr 1fr;
          gap: 20px;
          margin-bottom: 30px;
        }
        
        .chart-container {
          background: white;
          padding: 20px;
          border-radius: 8px;
          box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        
        .chart-container h3 {
          margin: 0 0 20px 0;
          color: #333;
        }
        
        .analysis-row {
          display: grid;
          grid-template-columns: 1fr 1fr;
          gap: 20px;
        }
        
        .analysis-panel {
          background: white;
          padding: 20px;
          border-radius: 8px;
          box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        
        .analysis-panel h3 {
          margin: 0 0 15px 0;
          color: #333;
        }
        
        .insight-item {
          padding: 10px;
          margin-bottom: 10px;
          border-left: 4px solid #007bff;
          background: #f8f9fa;
          border-radius: 4px;
        }
        
        .insight-item.warning {
          border-left-color: #ffc107;
        }
        
        .insight-item.error {
          border-left-color: #dc3545;
        }
        
        .alert-item {
          padding: 12px;
          margin-bottom: 8px;
          border-radius: 4px;
          border-left: 4px solid #dc3545;
          background: #f8d7da;
        }
        
        .alert-item.warning {
          border-left-color: #ffc107;
          background: #fff3cd;
        }
        
        .alert-item.info {
          border-left-color: #17a2b8;
          background: #d1ecf1;
        }
        
        @media (max-width: 768px) {
          .charts-row,
          .analysis-row {
            grid-template-columns: 1fr;
          }
          
          .metrics-row {
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
          }
        }
      </style>
    `;
    
    document.head.insertAdjacentHTML('beforeend', styles);
  }
  
  // 设置事件监听器
  setupEventListeners() {
    // 时间范围选择
    document.getElementById('timeRange').addEventListener('change', (e) => {
      this.updateTimeRange(e.target.value);
    });
    
    // 刷新按钮
    document.getElementById('refreshBtn').addEventListener('click', () => {
      this.refreshData();
    });
    
    // 导出按钮
    document.getElementById('exportBtn').addEventListener('click', () => {
      this.exportData();
    });
  }
  
  // 加载初始数据
  async loadInitialData() {
    try {
      const analysis = await this.dataAnalyzer.performAnalysis();
      this.updateDashboard(analysis);
    } catch (error) {
      console.error('加载初始数据失败:', error);
      this.showError('数据加载失败,请稍后重试');
    }
  }
  
  // 启动实时更新
  startRealTimeUpdates() {
    this.updateInterval = setInterval(async () => {
      try {
        const analysis = await this.dataAnalyzer.performAnalysis();
        this.updateDashboard(analysis);
      } catch (error) {
        console.error('实时更新失败:', error);
      }
    }, this.options.refreshInterval);
  }
  
  // 更新仪表板
  updateDashboard(analysis) {
    this.updateMetricCards(analysis);
    this.updateCharts(analysis);
    this.updateInsights(analysis);
    this.updateAlerts(analysis);
  }
  
  // 更新指标卡片
  updateMetricCards(analysis) {
    const { errorAnalysis, performanceAnalysis, userBehaviorAnalysis } = analysis;
    
    // 错误率
    const errorRate = errorAnalysis.errorRate;
    this.updateMetricCard('errorRate', {
      value: `${errorRate.toFixed(2)}%`,
      trend: this.calculateTrend(errorRate, 'error'),
      status: errorRate > 5 ? 'error' : errorRate > 2 ? 'warning' : 'good'
    });
    
    // 性能评分
    const performanceScore = this.calculatePerformanceScore(performanceAnalysis);
    this.updateMetricCard('performanceScore', {
      value: performanceScore,
      trend: this.calculateTrend(performanceScore, 'performance'),
      status: performanceScore < 60 ? 'error' : performanceScore < 80 ? 'warning' : 'good'
    });
    
    // 用户满意度
    const userSatisfaction = userBehaviorAnalysis.engagementScore;
    this.updateMetricCard('userSatisfaction', {
      value: `${userSatisfaction}/100`,
      trend: this.calculateTrend(userSatisfaction, 'satisfaction'),
      status: userSatisfaction < 60 ? 'error' : userSatisfaction < 80 ? 'warning' : 'good'
    });
    
    // 活跃用户
    const activeUsers = userBehaviorAnalysis.sessionAnalysis.totalSessions || 0;
    this.updateMetricCard('activeUsers', {
      value: activeUsers.toLocaleString(),
      trend: this.calculateTrend(activeUsers, 'users'),
      status: 'info'
    });
  }
  
  // 更新单个指标卡片
  updateMetricCard(cardId, data) {
    const card = document.getElementById(cardId);
    const valueElement = card.querySelector('.metric-value');
    const trendElement = card.querySelector('.metric-trend');
    
    valueElement.textContent = data.value;
    trendElement.textContent = data.trend.text;
    trendElement.className = `metric-trend ${data.trend.direction}`;
    
    // 更新卡片状态颜色
    card.className = `metric-card ${data.status}`;
  }
  
  // 计算趋势
  calculateTrend(currentValue, type) {
    // 这里应该与历史数据比较,简化实现
    const change = Math.random() * 20 - 10; // 模拟变化
    const direction = change > 0 ? 'positive' : change < 0 ? 'negative' : 'neutral';
    
    let text = '';
    if (Math.abs(change) < 1) {
      text = '保持稳定';
    } else {
      text = `${change > 0 ? '↑' : '↓'} ${Math.abs(change).toFixed(1)}%`;
    }
    
    return { direction, text };
  }
  
  // 计算性能评分
  calculatePerformanceScore(performanceAnalysis) {
    const { coreWebVitals, resourceAnalysis, longTaskAnalysis } = performanceAnalysis;
    
    let score = 100;
    
    // LCP评分 (最大内容绘制)
    if (coreWebVitals.lcp > 4000) {
      score -= 30;
    } else if (coreWebVitals.lcp > 2500) {
      score -= 15;
    }
    
    // FID评分 (首次输入延迟)
    if (coreWebVitals.fid > 300) {
      score -= 25;
    } else if (coreWebVitals.fid > 100) {
      score -= 10;
    }
    
    // CLS评分 (累积布局偏移)
    if (coreWebVitals.cls > 0.25) {
      score -= 20;
    } else if (coreWebVitals.cls > 0.1) {
      score -= 10;
    }
    
    // 长任务影响
    score -= Math.min(15, longTaskAnalysis.impactScore / 10);
    
    return Math.max(0, Math.round(score));
  }
  
  // 更新图表
  updateCharts(analysis) {
    this.updateErrorTrendChart(analysis.errorAnalysis);
    this.updatePerformanceChart(analysis.performanceAnalysis);
    this.updateUserHeatmap(analysis.userBehaviorAnalysis);
  }
  
  // 更新错误趋势图表
  updateErrorTrendChart(errorAnalysis) {
    const canvas = document.getElementById('errorTrendChart');
    const ctx = canvas.getContext('2d');
    
    // 简化的图表实现
    const data = errorAnalysis.trends || [];
    this.renderLineChart(ctx, data, {
      title: '错误趋势',
      color: '#dc3545',
      yAxisLabel: '错误数量'
    });
  }
  
  // 更新性能图表
  updatePerformanceChart(performanceAnalysis) {
    const canvas = document.getElementById('performanceChart');
    const ctx = canvas.getContext('2d');
    
    const data = [
      { label: 'LCP', value: performanceAnalysis.coreWebVitals.lcp },
      { label: 'FID', value: performanceAnalysis.coreWebVitals.fid },
      { label: 'CLS', value: performanceAnalysis.coreWebVitals.cls * 1000 }
    ];
    
    this.renderBarChart(ctx, data, {
      title: '核心性能指标',
      colors: ['#007bff', '#28a745', '#ffc107']
    });
  }
  
  // 更新用户行为热图
  updateUserHeatmap(userBehaviorAnalysis) {
    const container = document.getElementById('userHeatmap');
    const timeAnalysis = userBehaviorAnalysis.timeAnalysis;
    
    if (!timeAnalysis) {
      container.innerHTML = '<p>暂无用户行为数据</p>';
      return;
    }
    
    const hourlyData = timeAnalysis.hourlyActivity;
    const maxActivity = Math.max(...hourlyData);
    
    let heatmapHTML = '<div class="heatmap-grid">';
    
    for (let hour = 0; hour < 24; hour++) {
      const activity = hourlyData[hour] || 0;
      const intensity = maxActivity > 0 ? activity / maxActivity : 0;
      const opacity = Math.max(0.1, intensity);
      
      heatmapHTML += `
        <div class="heatmap-cell" 
             style="background-color: rgba(0, 123, 255, ${opacity})"
             title="${hour}:00 - ${activity} 次交互">
          ${hour}
        </div>
      `;
    }
    
    heatmapHTML += '</div>';
    
    // 添加热图样式
    const heatmapStyles = `
      <style>
        .heatmap-grid {
          display: grid;
          grid-template-columns: repeat(12, 1fr);
          gap: 2px;
          margin-top: 10px;
        }
        
        .heatmap-cell {
          aspect-ratio: 1;
          display: flex;
          align-items: center;
          justify-content: center;
          border-radius: 4px;
          font-size: 12px;
          color: white;
          font-weight: bold;
          cursor: pointer;
          transition: transform 0.2s;
        }
        
        .heatmap-cell:hover {
          transform: scale(1.1);
        }
      </style>
    `;
    
    if (!document.querySelector('.heatmap-styles')) {
      document.head.insertAdjacentHTML('beforeend', heatmapStyles.replace('<style>', '<style class="heatmap-styles">'));
    }
    
    container.innerHTML = heatmapHTML;
  }
  
  // 渲染折线图
  renderLineChart(ctx, data, options) {
    const canvas = ctx.canvas;
    const width = canvas.width;
    const height = canvas.height;
    
    ctx.clearRect(0, 0, width, height);
    
    if (!data || data.length === 0) {
      ctx.fillStyle = '#666';
      ctx.font = '14px Arial';
      ctx.textAlign = 'center';
      ctx.fillText('暂无数据', width / 2, height / 2);
      return;
    }
    
    // 简化的折线图实现
    const padding = 40;
    const chartWidth = width - padding * 2;
    const chartHeight = height - padding * 2;
    
    const maxValue = Math.max(...data.map(d => d.value));
    const minValue = Math.min(...data.map(d => d.value));
    const valueRange = maxValue - minValue || 1;
    
    ctx.strokeStyle = options.color;
    ctx.lineWidth = 2;
    ctx.beginPath();
    
    data.forEach((point, index) => {
      const x = padding + (index / (data.length - 1)) * chartWidth;
      const y = padding + chartHeight - ((point.value - minValue) / valueRange) * chartHeight;
      
      if (index === 0) {
        ctx.moveTo(x, y);
      } else {
        ctx.lineTo(x, y);
      }
    });
    
    ctx.stroke();
  }
  
  // 渲染柱状图
  renderBarChart(ctx, data, options) {
    const canvas = ctx.canvas;
    const width = canvas.width;
    const height = canvas.height;
    
    ctx.clearRect(0, 0, width, height);
    
    if (!data || data.length === 0) {
      ctx.fillStyle = '#666';
      ctx.font = '14px Arial';
      ctx.textAlign = 'center';
      ctx.fillText('暂无数据', width / 2, height / 2);
      return;
    }
    
    const padding = 40;
    const chartWidth = width - padding * 2;
    const chartHeight = height - padding * 2;
    const barWidth = chartWidth / data.length * 0.8;
    const barSpacing = chartWidth / data.length * 0.2;
    
    const maxValue = Math.max(...data.map(d => d.value));
    
    data.forEach((item, index) => {
      const barHeight = (item.value / maxValue) * chartHeight;
      const x = padding + index * (barWidth + barSpacing);
      const y = padding + chartHeight - barHeight;
      
      ctx.fillStyle = options.colors[index % options.colors.length];
      ctx.fillRect(x, y, barWidth, barHeight);
      
      // 绘制标签
      ctx.fillStyle = '#333';
      ctx.font = '12px Arial';
      ctx.textAlign = 'center';
      ctx.fillText(item.label, x + barWidth / 2, height - 10);
       ctx.fillText(item.value.toFixed(0), x + barWidth / 2, y - 5);
     });
   }
   
   // 更新智能分析建议
   updateInsights(analysis) {
     const container = document.getElementById('intelligentInsights');
     const insights = this.generateInsights(analysis);
     
     let insightsHTML = '';
     insights.forEach(insight => {
       insightsHTML += `
         <div class="insight-item ${insight.type}">
           <strong>${insight.title}</strong>
           <p>${insight.description}</p>
           ${insight.action ? `<small>建议: ${insight.action}</small>` : ''}
         </div>
       `;
     });
     
     container.innerHTML = insightsHTML || '<p>暂无分析建议</p>';
   }
   
   // 生成智能分析建议
   generateInsights(analysis) {
     const insights = [];
     const { errorAnalysis, performanceAnalysis, userBehaviorAnalysis } = analysis;
     
     // 错误率分析
     if (errorAnalysis.errorRate > 5) {
       insights.push({
         type: 'error',
         title: '错误率过高',
         description: `当前错误率为 ${errorAnalysis.errorRate.toFixed(2)}%,超过了5%的警戒线`,
         action: '建议立即检查最近的代码部署,排查高频错误原因'
       });
     } else if (errorAnalysis.errorRate > 2) {
       insights.push({
         type: 'warning',
         title: '错误率偏高',
         description: `当前错误率为 ${errorAnalysis.errorRate.toFixed(2)}%,需要关注`,
         action: '建议分析错误类型分布,优化容错处理'
       });
     }
     
     // 性能分析
     const performanceScore = this.calculatePerformanceScore(performanceAnalysis);
     if (performanceScore < 60) {
       insights.push({
         type: 'error',
         title: '性能严重不足',
         description: `性能评分仅为 ${performanceScore},用户体验较差`,
         action: '建议进行性能优化:代码分割、资源压缩、CDN加速等'
       });
     } else if (performanceScore < 80) {
       insights.push({
         type: 'warning',
         title: '性能有待提升',
         description: `性能评分为 ${performanceScore},还有优化空间`,
         action: '建议优化Core Web Vitals指标,特别关注LCP和FID'
       });
     }
     
     // 长任务分析
     if (performanceAnalysis.longTaskAnalysis.totalCount > 10) {
       insights.push({
         type: 'warning',
         title: '长任务过多',
         description: `检测到 ${performanceAnalysis.longTaskAnalysis.totalCount} 个长任务`,
         action: '建议使用Web Workers或时间切片技术优化长任务'
       });
     }
     
     // 布局偏移分析
     if (performanceAnalysis.layoutShiftAnalysis.impactLevel === 'poor') {
       insights.push({
         type: 'error',
         title: '布局偏移严重',
         description: `CLS评分为 ${performanceAnalysis.layoutShiftAnalysis.cumulativeScore}`,
         action: '建议为图片和广告设置固定尺寸,避免动态内容插入'
       });
     }
     
     // 用户参与度分析
     if (userBehaviorAnalysis.engagementScore < 60) {
       insights.push({
         type: 'warning',
         title: '用户参与度较低',
         description: `用户参与度评分为 ${userBehaviorAnalysis.engagementScore}`,
         action: '建议优化用户界面和交互体验,增加用户粘性'
       });
     }
     
     // 会话分析
     const sessionAnalysis = userBehaviorAnalysis.sessionAnalysis;
     if (sessionAnalysis.averageSessionDuration < 30000) { // 30秒
       insights.push({
         type: 'info',
         title: '会话时长较短',
         description: `平均会话时长为 ${Math.round(sessionAnalysis.averageSessionDuration / 1000)}`,
         action: '建议分析用户流失点,优化页面内容和导航'
       });
     }
     
     return insights;
   }
   
   // 更新告警列表
   updateAlerts(analysis) {
     const container = document.getElementById('alertsList');
     const alerts = this.generateAlerts(analysis);
     
     let alertsHTML = '';
     alerts.forEach(alert => {
       alertsHTML += `
         <div class="alert-item ${alert.severity}">
           <div class="alert-header">
             <strong>${alert.title}</strong>
             <span class="alert-time">${alert.time}</span>
           </div>
           <p>${alert.message}</p>
         </div>
       `;
     });
     
     container.innerHTML = alertsHTML || '<p>暂无告警信息</p>';
   }
   
   // 生成告警信息
   generateAlerts(analysis) {
     const alerts = [];
     const now = new Date();
     
     // 基于分析结果生成告警
     const { errorAnalysis, performanceAnalysis } = analysis;
     
     if (errorAnalysis.errorRate > 10) {
       alerts.push({
         severity: 'error',
         title: '严重错误告警',
         message: `错误率达到 ${errorAnalysis.errorRate.toFixed(2)}%,需要立即处理`,
         time: now.toLocaleTimeString()
       });
     }
     
     if (performanceAnalysis.coreWebVitals.lcp > 4000) {
       alerts.push({
         severity: 'warning',
         title: 'LCP性能告警',
         message: `最大内容绘制时间为 ${performanceAnalysis.coreWebVitals.lcp}ms,超过4秒阈值`,
         time: now.toLocaleTimeString()
       });
     }
     
     if (performanceAnalysis.longTaskAnalysis.totalCount > 20) {
       alerts.push({
         severity: 'warning',
         title: '长任务告警',
         message: `检测到 ${performanceAnalysis.longTaskAnalysis.totalCount} 个长任务,可能影响用户体验`,
         time: now.toLocaleTimeString()
       });
     }
     
     return alerts.slice(0, 5); // 只显示最近5条告警
   }
   
   // 更新时间范围
   updateTimeRange(range) {
     this.currentTimeRange = range;
     this.refreshData();
   }
   
   // 刷新数据
   async refreshData() {
     try {
       const analysis = await this.dataAnalyzer.performAnalysis();
       this.updateDashboard(analysis);
       this.showSuccess('数据已刷新');
     } catch (error) {
       console.error('刷新数据失败:', error);
       this.showError('数据刷新失败');
     }
   }
   
   // 导出数据
   exportData() {
     try {
       const data = {
         timestamp: new Date().toISOString(),
         timeRange: this.currentTimeRange,
         analysis: this.lastAnalysis
       };
       
       const blob = new Blob([JSON.stringify(data, null, 2)], {
         type: 'application/json'
       });
       
       const url = URL.createObjectURL(blob);
       const a = document.createElement('a');
       a.href = url;
       a.download = `sentry-analysis-${Date.now()}.json`;
       document.body.appendChild(a);
       a.click();
       document.body.removeChild(a);
       URL.revokeObjectURL(url);
       
       this.showSuccess('数据已导出');
     } catch (error) {
       console.error('导出数据失败:', error);
       this.showError('数据导出失败');
     }
   }
   
   // 处理窗口大小调整
   handleResize() {
     // 重新渲染图表
     if (this.lastAnalysis) {
       this.updateCharts(this.lastAnalysis);
     }
   }
   
   // 显示成功消息
   showSuccess(message) {
     this.showNotification(message, 'success');
   }
   
   // 显示错误消息
   showError(message) {
     this.showNotification(message, 'error');
   }
   
   // 显示通知
   showNotification(message, type) {
     const notification = document.createElement('div');
     notification.className = `notification ${type}`;
     notification.textContent = message;
     
     notification.style.cssText = `
       position: fixed;
       top: 20px;
       right: 20px;
       padding: 12px 20px;
       border-radius: 4px;
       color: white;
       font-weight: bold;
       z-index: 1000;
       animation: slideIn 0.3s ease-out;
       background: ${type === 'success' ? '#28a745' : '#dc3545'};
     `;
     
     document.body.appendChild(notification);
     
     setTimeout(() => {
       notification.style.animation = 'slideOut 0.3s ease-in';
       setTimeout(() => {
         document.body.removeChild(notification);
       }, 300);
     }, 3000);
   }
   
   // 销毁仪表板
   destroy() {
     if (this.updateInterval) {
       clearInterval(this.updateInterval);
     }
     
     if (this.options.autoResize) {
       window.removeEventListener('resize', this.handleResize.bind(this));
     }
     
     this.container.innerHTML = '';
   }
 }
 
 // 告警管理器
 class AlertManager {
   constructor(options = {}) {
     this.options = {
       maxAlerts: 100,
       retentionTime: 24 * 60 * 60 * 1000, // 24小时
       ...options
     };
     
     this.alerts = [];
     this.subscribers = [];
   }
   
   // 添加告警
   addAlert(alert) {
     const alertWithId = {
       id: Date.now() + Math.random(),
       timestamp: Date.now(),
       ...alert
     };
     
     this.alerts.unshift(alertWithId);
     
     // 限制告警数量
     if (this.alerts.length > this.options.maxAlerts) {
       this.alerts = this.alerts.slice(0, this.options.maxAlerts);
     }
     
     // 通知订阅者
     this.notifySubscribers(alertWithId);
     
     // 清理过期告警
     this.cleanupExpiredAlerts();
   }
   
   // 获取告警列表
   getAlerts(filter = {}) {
     let filteredAlerts = [...this.alerts];
     
     if (filter.severity) {
       filteredAlerts = filteredAlerts.filter(alert => alert.severity === filter.severity);
     }
     
     if (filter.since) {
       filteredAlerts = filteredAlerts.filter(alert => alert.timestamp >= filter.since);
     }
     
     if (filter.limit) {
       filteredAlerts = filteredAlerts.slice(0, filter.limit);
     }
     
     return filteredAlerts;
   }
   
   // 订阅告警
   subscribe(callback) {
     this.subscribers.push(callback);
     
     // 返回取消订阅函数
     return () => {
       const index = this.subscribers.indexOf(callback);
       if (index > -1) {
         this.subscribers.splice(index, 1);
       }
     };
   }
   
   // 通知订阅者
   notifySubscribers(alert) {
     this.subscribers.forEach(callback => {
       try {
         callback(alert);
       } catch (error) {
         console.error('告警通知失败:', error);
       }
     });
   }
   
   // 清理过期告警
   cleanupExpiredAlerts() {
     const now = Date.now();
     this.alerts = this.alerts.filter(alert => 
       now - alert.timestamp < this.options.retentionTime
     );
   }
   
   // 清除所有告警
   clearAlerts() {
     this.alerts = [];
   }
 }
 
 // 使用示例
 const dashboard = new IntelligentMonitoringDashboard('dashboard-container', {
   refreshInterval: 30000,
   theme: 'light',
   autoResize: true
 });
 
 // 监听告警
 const alertManager = new AlertManager();
 alertManager.subscribe(alert => {
   console.log('新告警:', alert);
   
   // 可以在这里添加更多的告警处理逻辑
   // 比如发送邮件、推送通知等
 });

4. 核心价值与实施建议

4.1 核心价值

数据驱动决策

  • 基于真实用户数据进行产品优化
  • 量化用户体验指标
  • 识别性能瓶颈和改进机会

智能化监控

  • 自动异常检测和告警
  • 智能分析建议生成
  • 实时性能监控和优化

可视化洞察

  • 直观的数据展示和趋势分析
  • 多维度数据关联分析
  • 自定义仪表板和报告

4.2 实施建议

分阶段实施

  1. 基础阶段: 实现数据收集和基本分析
  2. 进阶阶段: 添加智能分析和可视化
  3. 高级阶段: 构建完整的监控体系

团队协作

  • 开发团队负责数据收集和技术实现
  • 产品团队参与指标定义和分析
  • 运维团队负责监控和告警处理

持续改进

  • 定期评估和优化监控策略
  • 根据业务需求调整分析维度
  • 持续完善告警规则和阈值

5. 未来发展趋势

5.1 AI驱动的智能分析

机器学习预测

  • 基于历史数据预测性能趋势
  • 智能异常检测和根因分析
  • 自动化性能优化建议

自然语言处理

  • 智能错误分类和聚合
  • 自动生成分析报告
  • 语音交互式数据查询

5.2 边缘计算集成

边缘数据处理

  • 就近处理用户数据,减少延迟
  • 实时性能监控和优化
  • 分布式数据分析架构

智能缓存策略

  • 基于用户行为的智能缓存
  • 动态资源优化和分发
  • 边缘计算性能提升

5.3 隐私保护增强

数据脱敏技术

  • 自动识别和保护敏感信息
  • 差分隐私数据分析
  • 联邦学习模型训练

合规性自动化

  • 自动化GDPR合规检查
  • 数据生命周期管理
  • 隐私影响评估工具

总结

前端Sentry数据分析与可视化是构建现代Web应用监控体系的重要组成部分。通过系统化的数据收集、智能化的分析处理和直观的可视化展示,我们可以:

  1. 全面了解应用状态: 从错误监控到性能分析,从用户行为到业务指标
  2. 快速识别问题: 通过智能告警和异常检测,及时发现和解决问题
  3. 数据驱动优化: 基于真实数据进行产品决策和性能优化
  4. 提升用户体验: 通过持续监控和改进,不断提升用户满意度

随着技术的不断发展,前端监控将更加智能化、自动化和个性化。掌握这些技术和方法,将帮助我们构建更加稳定、高效和用户友好的Web应用。


网站公告

今日签到

点亮在社区的每一天
去签到