一、实现代码:
1、logReporter.js
// 初始化日志 Worker
const logWorker = new Worker('logReporter.worker.js');

/**
 * 上报日志
 * @param {Object} data - 日志数据
 * @param {string} data.level - 日志级别(debug/info/warn/error)
 * @param {string} data.message - 日志信息
 * @param {Object} [data.extra] - 额外信息
 */
export const reportLog = (data) => {
  if (typeof data !== 'object' || !data.level || !data.message) {
    console.error('日志格式错误');
    return;
  }
  
  // 发送日志到 Worker
  logWorker.postMessage({
    type: 'LOG',
    data
  });
};

// 暴露常用日志级别快捷方法
export const logger = {
  debug: (message, extra) => reportLog({ level: 'debug', message, extra }),
  info: (message, extra) => reportLog({ level: 'info', message, extra }),
  warn: (message, extra) => reportLog({ level: 'warn', message, extra }),
  error: (message, extra) => reportLog({ level: 'error', message, extra })
};
2、logReporter.worker.js
// 配置上报地址
const REPORT_URL = '/api/log/report';

// 批量上报配置
const BATCH_CONFIG = {
  maxCount: 20,    // 最大批量数
  delay: 3000      // 延迟上报时间(ms)
};

let logQueue = [];
let timer = null;

// 处理日志上报
function handleReport() {
  if (logQueue.length === 0) return;
  
  // 复制并清空队列
  const reports = [...logQueue];
  logQueue = [];
  
  // 清除定时器
  if (timer) {
    clearTimeout(timer);
    timer = null;
  }
  
  // 发送日志
  fetch(REPORT_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(reports),
    keepalive: true  // 页面卸载时仍能发送
  }).catch(err => console.error('日志上报失败:', err));
}

// 监听主线程消息
self.onmessage = (e) => {
  const { type, data } = e.data;
  
  if (type === 'LOG') {
    // 添加日志到队列
    logQueue.push({
      ...data,
      timestamp: Date.now(),
      url: self.location.href
    });
    
    // 达到最大数量立即上报
    if (logQueue.length >= BATCH_CONFIG.maxCount) {
      handleReport();
    } 
    // 否则延迟上报
    else if (!timer) {
      timer = setTimeout(handleReport, BATCH_CONFIG.delay);
    }
  }
};

// 监听页面关闭事件,确保剩余日志发送
self.addEventListener('beforeunload', handleReport);
3、基本用法:
import { logger } from './logReporter.js';

// 上报不同级别日志
logger.info('用户登录', { userId: '123', method: 'password' });
logger.error('支付失败', { orderId: '456', error: '余额不足' });
二、核心特性:
  • 批量上报:减少网络请求次数,达到阈值或超时后自动上报
  • 异步处理:所有上报操作在 Worker 中执行,不阻塞主线程
  • 自动附加:日志会自动添加时间戳和当前页面 URL
  • 页面卸载保护:使用 keepalive 和 beforeunload 确保日志能正常发送
三、注意事项:
  • 需要将两个文件放在正确路径,并确保 Worker 脚本能被正确加载
  • 跨域环境下需要配置相应的 CORS 策略
  • 可根据实际需求调整BATCH_CONFIG 中的批量参数和上报地址
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐