文章目录
- 一、实现代码:
- 1、logReporter.js
- 2、logReporter.worker.js
- 3、基本用法:
- 二、核心特性:
- 三、注意事项:
一、实现代码:
1、logReporter.js
const logWorker = new Worker('logReporter.worker.js');
export const reportLog = (data) => {if (typeof data !== 'object' || !data.level || !data.message) {console.error('日志格式错误');return;}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
};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 中的批量参数和上报地址