LogRocket 最佳实践 #
概述 #
本章总结了 LogRocket 在生产环境中的最佳实践,帮助你最大化监控效果,同时保护用户隐私和优化成本。
text
┌─────────────────────────────────────────────────────────────┐
│ 最佳实践概览 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 🚀 性能优化 │
│ - 减少对应用性能的影响 │
│ - 优化数据收集 │
│ │
│ 🔒 隐私保护 │
│ - 敏感数据处理 │
│ - 合规性考虑 │
│ │
│ 💰 成本控制 │
│ - 采样策略 │
│ - 数据保留 │
│ │
│ 👥 团队协作 │
│ - 工作流集成 │
│ - 告警管理 │
│ │
│ 📊 数据分析 │
│ - 指标选择 │
│ - 报告策略 │
│ │
└─────────────────────────────────────────────────────────────┘
性能优化 #
SDK 加载优化 #
javascript
// 推荐:异步加载 LogRocket SDK
(function() {
var script = document.createElement('script');
script.src = 'https://cdn.lr-ingest.io/LogRocket.min.js';
script.async = true;
script.onload = function() {
LogRocket.init('your-app-id/app-name');
};
document.head.appendChild(script);
})();
// 或者使用动态 import
async function initLogRocket() {
if (process.env.NODE_ENV === 'production') {
const LogRocket = await import('logrocket');
LogRocket.init('your-app-id/app-name');
}
}
配置优化 #
javascript
LogRocket.init('your-app-id/app-name', {
// 控制台日志优化
console: {
isEnabled: true,
isError: true,
isWarn: true,
isInfo: false, // 生产环境关闭 info
isDebug: false, // 生产环境关闭 debug
isLog: false // 生产环境关闭 log
},
// DOM 记录优化
dom: {
isEnabled: true,
inputSanitizer: true,
textSanitizer: true
},
// 网络请求优化
network: {
isEnabled: true,
requestSanitizer: function(request) {
// 只记录关键请求
if (request.url.includes('/api/health')) {
return null;
}
return request;
}
},
// 关闭调试日志
shouldDebugLog: false
});
采样策略 #
text
┌─────────────────────────────────────────────────────────────┐
│ 采样策略 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 推荐采样率: │
│ │
│ 小型应用(< 10K 用户/天): │
│ - 会话采样:100% │
│ - 错误采样:100% │
│ - 性能采样:100% │
│ │
│ 中型应用(10K-100K 用户/天): │
│ - 会话采样:50% │
│ - 错误采样:100% │
│ - 性能采样:50% │
│ │
│ 大型应用(> 100K 用户/天): │
│ - 会话采样:10-20% │
│ - 错误采样:100% │
│ - 性能采样:10-20% │
│ │
│ 注意:错误始终建议 100% 采样 │
│ │
└─────────────────────────────────────────────────────────────┘
javascript
// 智能采样实现
function shouldRecordSession() {
const user = getCurrentUser();
// VIP 用户始终记录
if (user.isPremium) {
return true;
}
// 测试用户不记录
if (user.isTestUser) {
return false;
}
// 随机采样
return Math.random() < 0.2; // 20% 采样率
}
if (shouldRecordSession()) {
LogRocket.init('your-app-id/app-name');
}
隐私保护 #
敏感数据处理 #
javascript
LogRocket.init('your-app-id/app-name', {
dom: {
inputSanitizer: function(el, value) {
// 密码字段
if (el.type === 'password') {
return '';
}
// 信用卡号
if (el.name === 'cardNumber' || el.id === 'card-number') {
return value.replace(/\d(?=\d{4})/g, '*');
}
// CVV
if (el.name === 'cvv' || el.id === 'cvv') {
return '***';
}
// 社会安全号
if (el.name === 'ssn' || el.id === 'ssn') {
return '***-**-****';
}
// 身份证号
if (el.name === 'idNumber' || el.id === 'id-number') {
return '******************';
}
return value;
},
textSanitizer: function(text, element) {
// 屏蔽敏感文本
if (element.closest('[data-private]')) {
return '[REDACTED]';
}
return text;
}
},
network: {
requestSanitizer: function(request) {
// 过滤敏感请求
if (request.url.includes('/api/auth')) {
if (request.body) {
try {
const body = JSON.parse(request.body);
if (body.password) body.password = '[REDACTED]';
if (body.token) body.token = '[REDACTED]';
request.body = JSON.stringify(body);
} catch (e) {}
}
}
return request;
},
responseSanitizer: function(response) {
// 过滤敏感响应
if (response.url.includes('/api/user/sensitive')) {
return null;
}
if (response.body) {
try {
const body = JSON.parse(response.body);
if (body.ssn) body.ssn = '[REDACTED]';
if (body.creditCard) body.creditCard = '[REDACTED]';
response.body = JSON.stringify(body);
} catch (e) {}
}
return response;
}
}
});
HTML 属性屏蔽 #
html
<!-- 使用 data-private 属性屏蔽敏感内容 -->
<div data-private>
这里的内容不会被记录
</div>
<!-- 敏感输入字段 -->
<input type="text" name="creditCard" data-private />
<!-- 敏感区域 -->
<div class="user-sensitive-info" data-private>
<p>Social Security Number: 123-45-6789</p>
</div>
GDPR 合规 #
text
┌─────────────────────────────────────────────────────────────┐
│ GDPR 合规建议 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 用户同意 │
│ - 在 Cookie 同意弹窗中包含 LogRocket │
│ - 提供选择退出选项 │
│ │
│ 2. 数据最小化 │
│ - 只收集必要的数据 │
│ - 屏蔽敏感信息 │
│ │
│ 3. 数据保留 │
│ - 设置合理的数据保留期限 │
│ - 定期清理旧数据 │
│ │
│ 4. 用户权利 │
│ - 提供数据删除机制 │
│ - 支持数据导出请求 │
│ │
│ 5. 数据处理协议 │
│ - 与 LogRocket 签署 DPA │
│ - 明确数据处理责任 │
│ │
└─────────────────────────────────────────────────────────────┘
javascript
// 用户同意管理
function initLogRocketWithConsent() {
const hasConsent = checkUserConsent('analytics');
if (hasConsent) {
LogRocket.init('your-app-id/app-name');
}
}
// 用户选择退出
function handleOptOut() {
// 停止记录
LogRocket.identify(null);
// 设置退出标记
localStorage.setItem('logrocket-opt-out', 'true');
}
// 检查用户同意
function checkUserConsent(type) {
const consent = localStorage.getItem('user-consent');
if (!consent) return false;
const consentData = JSON.parse(consent);
return consentData[type] === true;
}
成本控制 #
数据量优化 #
javascript
// 控制数据收集量
LogRocket.init('your-app-id/app-name', {
// 限制网络请求记录
network: {
isEnabled: true,
requestSanitizer: function(request) {
// 不记录静态资源请求
if (request.url.match(/\.(css|js|png|jpg|gif|svg|woff|woff2)$/)) {
return null;
}
// 不记录健康检查请求
if (request.url.includes('/health') || request.url.includes('/ping')) {
return null;
}
// 限制请求体大小
if (request.body && request.body.length > 10000) {
request.body = request.body.substring(0, 10000) + '...[truncated]';
}
return request;
}
}
});
按环境区分 #
javascript
// 不同环境使用不同配置
const logrocketConfig = {
development: {
enabled: false
},
staging: {
enabled: true,
samplingRate: 1.0,
console: { isDebug: true }
},
production: {
enabled: true,
samplingRate: 0.2,
console: { isDebug: false }
}
};
const env = process.env.NODE_ENV || 'development';
const config = logrocketConfig[env];
if (config.enabled) {
LogRocket.init('your-app-id/app-name', {
...config
});
}
数据保留策略 #
text
┌─────────────────────────────────────────────────────────────┐
│ 数据保留建议 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 根据需求选择合适的保留期限: │
│ │
│ 调试和问题排查: │
│ - 建议:30-90 天 │
│ - 足够复现和修复问题 │
│ │
│ 趋势分析: │
│ - 建议:90-180 天 │
│ - 可以分析季节性趋势 │
│ │
│ 合规审计: │
│ - 建议:根据法规要求 │
│ - 可能需要 1-2 年 │
│ │
│ 成本优化: │
│ - 定期清理不需要的旧数据 │
│ - 导出重要数据后删除 │
│ │
└─────────────────────────────────────────────────────────────┘
团队协作 #
告警管理 #
text
┌─────────────────────────────────────────────────────────────┐
│ 告警最佳实践 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 告警分级: │
│ │
│ P0 - 紧急 │
│ - 影响核心业务功能 │
│ - 错误率突然飙升 │
│ - 通知:电话 + 短信 + Slack │
│ │
│ P1 - 高优先级 │
│ - 影响重要功能 │
│ - 性能严重下降 │
│ - 通知:Slack + 邮件 │
│ │
│ P2 - 中优先级 │
│ - 影响次要功能 │
│ - 新发现的错误 │
│ - 通知:Slack │
│ │
│ P3 - 低优先级 │
│ - 边缘情况 │
│ - 影响少数用户 │
│ - 通知:每日汇总邮件 │
│ │
└─────────────────────────────────────────────────────────────┘
工作流集成 #
javascript
// 与 Issue 跟踪系统集成
async function createIssueFromError(error) {
const sessionUrl = LogRocket.sessionURL;
const issue = {
title: `[LogRocket] ${error.type}: ${error.message}`,
body: `
## Error Details
- **Type**: ${error.type}
- **Message**: ${error.message}
- **URL**: ${error.url}
- **Browser**: ${error.browser}
- **First Seen**: ${error.firstSeen}
- **Users Affected**: ${error.userCount}
## Session Recording
[View Session](${sessionUrl})
## Stack Trace
\`\`\`
${error.stacktrace}
\`\`\`
## Context
- **User ID**: ${error.userId}
- **Environment**: ${error.environment}
`,
labels: ['bug', 'frontend', 'logrocket'],
priority: determinePriority(error)
};
return await createIssue(issue);
}
团队培训 #
text
┌─────────────────────────────────────────────────────────────┐
│ 团队培训建议 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 开发团队: │
│ 1. LogRocket 基础使用 │
│ 2. 错误追踪和分析 │
│ 3. 会话回放查看 │
│ 4. Source Map 配置 │
│ │
│ QA 团队: │
│ 1. 会话回放分析 │
│ 2. 性能指标解读 │
│ 3. Bug 报告最佳实践 │
│ │
│ 客服团队: │
│ 1. 查找用户会话 │
│ 2. 基础问题分析 │
│ 3. 会话链接分享 │
│ │
│ 产品团队: │
│ 1. 用户行为分析 │
│ 2. 性能报告解读 │
│ 3. UX 优化建议 │
│ │
└─────────────────────────────────────────────────────────────┘
错误处理最佳实践 #
错误分类处理 #
javascript
// 错误处理策略
const errorHandlingStrategy = {
// 关键错误 - 立即告警
critical: {
patterns: [
/Payment failed/,
/Checkout error/,
/Authentication failed/
],
action: 'immediate_alert',
channels: ['slack', 'email', 'pagerduty']
},
// 重要错误 - 记录并告警
important: {
patterns: [
/TypeError/,
/ReferenceError/,
/Network error/
],
action: 'log_and_alert',
channels: ['slack']
},
// 一般错误 - 仅记录
normal: {
patterns: [
/Validation error/,
/User input error/
],
action: 'log_only',
channels: []
},
// 忽略的错误
ignore: {
patterns: [
/Script error/,
/Non-Error promise rejection/,
/ResizeObserver loop limit exceeded/
],
action: 'ignore',
channels: []
}
};
function classifyError(error) {
const message = error.message || '';
for (const [level, config] of Object.entries(errorHandlingStrategy)) {
for (const pattern of config.patterns) {
if (pattern.test(message)) {
return { level, ...config };
}
}
}
return { level: 'normal', ...errorHandlingStrategy.normal };
}
错误忽略策略 #
javascript
// 配置错误忽略
const ignoredErrors = [
// 第三方脚本错误
'Script error.',
'Non-Error promise rejection captured',
// 浏览器扩展错误
'chrome-extension://',
'safari-extension://',
// 无害的错误
'ResizeObserver loop limit exceeded',
'Network request failed',
// 已知的第三方库问题
/__gCrWeb/,
/atomicFind/
];
function shouldIgnoreError(error) {
const message = error.message || '';
return ignoredErrors.some(pattern => {
if (typeof pattern === 'string') {
return message.includes(pattern);
}
return pattern.test(message);
});
}
性能监控最佳实践 #
关键指标选择 #
text
┌─────────────────────────────────────────────────────────────┐
│ 关键指标选择 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 电商网站: │
│ - LCP(商品图片加载) │
│ - FID(加入购物车响应) │
│ - 结账流程完成时间 │
│ - 支付成功率 │
│ │
│ 内容网站: │
│ - LCP(文章内容加载) │
│ - FCP(首次内容绘制) │
│ - 页面滚动深度 │
│ - 阅读完成率 │
│ │
│ SaaS 应用: │
│ - TTI(应用可交互时间) │
│ - API 响应时间 │
│ - 功能使用率 │
│ - 错误率 │
│ │
│ 移动端应用: │
│ - FID(触摸响应) │
│ - CLS(布局稳定性) │
│ - 网络请求时间 │
│ - 电量消耗 │
│ │
└─────────────────────────────────────────────────────────────┘
性能预算 #
javascript
// 性能预算配置
const performanceBudget = {
// Core Web Vitals
lcp: { target: 2500, warning: 4000 },
fid: { target: 100, warning: 300 },
cls: { target: 0.1, warning: 0.25 },
// 其他指标
fcp: { target: 1800, warning: 3000 },
tti: { target: 3800, warning: 7300 },
tbt: { target: 200, warning: 600 },
// 资源大小
js: { target: 300 * 1024, warning: 500 * 1024 },
css: { target: 50 * 1024, warning: 100 * 1024 },
images: { target: 500 * 1024, warning: 1000 * 1024 }
};
// 检查性能预算
function checkPerformanceBudget(metrics) {
const violations = [];
for (const [metric, budget] of Object.entries(performanceBudget)) {
const value = metrics[metric];
if (value > budget.target) {
violations.push({
metric,
value,
target: budget.target,
severity: value > budget.warning ? 'error' : 'warning'
});
}
}
return violations;
}
总结 #
检查清单 #
text
┌─────────────────────────────────────────────────────────────┐
│ LogRocket 使用检查清单 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 初始化配置: │
│ □ 正确配置 App ID │
│ □ 设置 release 版本号 │
│ □ 配置隐私屏蔽规则 │
│ □ 配置网络请求过滤 │
│ □ 设置合适的采样率 │
│ │
│ 隐私合规: │
│ □ 屏蔽密码字段 │
│ □ 屏蔽信用卡信息 │
│ □ 屏蔽个人身份信息 │
│ □ 配置用户同意机制 │
│ □ 提供退出选项 │
│ │
│ 错误追踪: │
│ □ 配置 Source Map 上传 │
│ □ 设置错误告警规则 │
│ □ 配置错误忽略规则 │
│ □ 集成 Issue 跟踪系统 │
│ │
│ 性能监控: │
│ □ 确认 Core Web Vitals 收集 │
│ □ 设置性能告警阈值 │
│ □ 配置性能预算 │
│ □ 定期审查性能报告 │
│ │
│ 团队协作: │
│ □ 配置团队成员权限 │
│ □ 集成 Slack/Teams │
│ □ 配置工作流集成 │
│ □ 团队培训完成 │
│ │
└─────────────────────────────────────────────────────────────┘
持续改进 #
text
┌─────────────────────────────────────────────────────────────┐
│ 持续改进建议 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 每周: │
│ - 审查新错误 │
│ - 检查性能趋势 │
│ - 处理告警 │
│ │
│ 每月: │
│ - 分析错误模式 │
│ - 优化性能瓶颈 │
│ - 更新告警规则 │
│ │
│ 每季度: │
│ - 评估监控效果 │
│ - 调整采样策略 │
│ - 优化成本 │
│ - 团队培训更新 │
│ │
└─────────────────────────────────────────────────────────────┘
恭喜完成! #
你已经完成了 LogRocket 文档的学习!现在你已经掌握了:
- LogRocket 的核心概念和功能
- 安装配置和基础使用
- 会话回放和性能监控
- 错误追踪和分析
- 高级功能和最佳实践
开始在你的项目中使用 LogRocket,提升前端监控能力,为用户提供更好的体验!
最后更新:2026-03-29