mini-sentry-sdk
v1.1.44
Published
Lightweight monitoring SDK for web applications with automatic sourcemap upload
Downloads
109
Maintainers
Readme
Mini-Sentry SDK 使用说明文档
📋 目录
🚀 快速开始
安装
npm install mini-sentry-sdk
# 或
yarn add mini-sentry-sdk基础使用
import { Monitor } from 'mini-sentry-sdk';
// 创建监控实例
const monitor = new Monitor({
projectId: 'your-project-id',
apiUrl: 'https://your-api-server.com/api'
});
// 初始化监控
monitor.init();📦 安装配置
1. 项目依赖
确保项目满足以下要求:
- Node.js >= 14.0.0
- 现代浏览器支持 (支持 ES2019)
- React >= 16.8.0 (如果使用 React 功能)
2. 安装方式
NPM/Yarn 安装 (推荐)
npm install mini-sentry-sdkCDN 引入
<script src="https://unpkg.com/mini-sentry-sdk/dist/index.min.js"></script>ES Module
import { Monitor, ErrorBoundary } from 'mini-sentry-sdk';CommonJS
const { Monitor, ErrorBoundary } = require('mini-sentry-sdk');🎯 基础用法
1. 创建监控实例
import { Monitor } from 'mini-sentry-sdk';
const monitor = new Monitor({
projectId: 'PROJ-123456', // 必需:项目ID
apiUrl: 'https://api.example.com', // 必需:上报接口地址
debug: false, // 可选:调试模式
sampleRate: 1, // 可选:采样率 (0-1)
maxBreadcrumbs: 10, // 可选:面包屑数量限制
defaultTags: { // 可选:默认标签
version: '1.0.0',
environment: 'production'
},
enabledModules: { // 可选:启用的模块
error: true,
performance: true,
behavior: true
}
});
// 初始化
await monitor.init();2. 手动错误上报
// 捕获错误
try {
throw new Error('Something went wrong');
} catch (error) {
monitor.captureError(error, {
userId: '12345',
action: 'button_click'
});
}
// 追踪事件
monitor.trackEvent('user', 'Login Success', {
loginMethod: 'email'
});
// 追踪性能指标
monitor.trackMetric('api_response_time', 1200, {
endpoint: '/api/users'
});
// 追踪业务事件
monitor.trackBusiness('purchase', {
orderId: 'ORDER-001',
amount: 99.99
});🔧 功能详解
错误监控
自动捕获的错误类型:
- JavaScript 运行时错误
- Promise 未处理的拒绝
- 资源加载错误
- HTTP 请求错误
- React 组件错误(配合 ErrorBoundary)
错误信息包含:
- 错误堆栈信息
- 用户行为轨迹(面包屑)
- 设备和浏览器信息
- 当前页面 URL
- 自定义标签
性能监控
监控指标:
- TTFB: 首字节时间
- FCP: 首次内容绘制
- LCP: 最大内容绘制
- DOM Ready: DOM 准备时间
- Load Complete: 页面完全加载时间
- Long Tasks: 长任务检测 (>50ms)
使用示例:
// 性能数据会自动收集,也可以手动获取状态
const vitalsStatus = monitor.getVitalsStatus();
console.log('性能指标状态:', vitalsStatus);
// 调试 LCP 问题
monitor.debugLcpSituation();用户行为追踪
自动追踪的行为:
- 页面访问和路由变化
- 用户点击事件
- 表单提交
- 滚动行为
- 页面可见性变化
- 页面停留时间
自定义行为追踪:
// 添加自定义面包屑
monitor.addBreadcrumb(
'user', // 类别
'Button clicked', // 消息
'info', // 级别
{ buttonId: 'submit' } // 数据
);网络监控
自动拦截:
- Fetch API 请求
- XMLHttpRequest 请求
- 请求失败和超时
- HTTP 状态码异常
🗺️ SourceMap 配置
1. Webpack 配置
步骤 1:配置 webpack.config.js
const MiniSentryWebpackPlugin = require('mini-sentry-sdk/webpack-plugin');
module.exports = {
// 生产环境必须开启 sourcemap
devtool: 'source-map',
plugins: [
new MiniSentryWebpackPlugin({
projectId: 'PROJ-123456',
apiUrl: 'https://your-api.com/sourcemap',
apiKey: 'your-api-key',
enabled: true, // 是否启用
uploadInDev: false, // 开发环境是否上传
include: ['**/*.map'], // 包含的文件
exclude: ['node_modules/**'], // 排除的文件
deleteAfterUpload: true, // 上传后删除本地文件
debug: false, // 调试模式
timeout: 30000, // 上传超时时间
retries: 3 // 重试次数
})
]
};步骤 2:构建项目
npm run build构建时插件会自动:
- 收集生成的 .map 文件
- 上传到指定的 API 地址
- 删除本地 sourcemap 文件(可配置)
2. 手动上传 SourceMap
import { SourceMapUploader } from 'mini-sentry-sdk';
const uploader = new SourceMapUploader({
apiUrl: 'https://your-api.com/sourcemap',
apiKey: 'your-api-key',
debug: true
});
// 上传文件
const result = await uploader.upload({
projectId: 'PROJ-123456',
timestamp: Date.now(),
files: [
{
filename: 'main.abc123.js.map',
content: sourceMapContent,
size: sourceMapContent.length,
jsFilename: 'main.abc123.js'
}
]
});3. SourceMap 最佳实践
文件命名规范:
- JS 文件:
main.abc123.js(包含 hash) - SourceMap 文件:
main.abc123.js.map
生产环境安全:
// webpack.config.js
module.exports = {
devtool: process.env.NODE_ENV === 'production' ? 'hidden-source-map' : 'eval-source-map'
};⚛️ React 集成
1. ErrorBoundary 使用
import React from 'react';
import { ErrorBoundary, Monitor } from 'mini-sentry-sdk';
// 创建监控实例
const monitor = new Monitor({
projectId: 'PROJ-123456',
apiUrl: 'https://your-api.com'
});
monitor.init();
function App() {
return (
<ErrorBoundary
projectId="PROJ-123456"
onError={(errorInfo) => {
// 可选:自定义错误处理
console.log('捕获到 React 错误:', errorInfo);
}}
tags={{
component: 'App',
version: '1.0.0'
}}
fallback={
<div>
<h2>页面出现错误</h2>
<p>我们已经记录了这个问题,请刷新页面重试。</p>
</div>
}
>
<YourApp />
</ErrorBoundary>
);
}2. Hook 集成
import { useEffect } from 'react';
import { Monitor } from 'mini-sentry-sdk';
const monitor = new Monitor({
projectId: 'PROJ-123456',
apiUrl: 'https://your-api.com'
});
export function useMonitoring() {
useEffect(() => {
monitor.init();
return () => {
monitor.destroy();
};
}, []);
return {
captureError: monitor.captureError.bind(monitor),
trackEvent: monitor.trackEvent.bind(monitor),
trackMetric: monitor.trackMetric.bind(monitor)
};
}
// 使用
function MyComponent() {
const { captureError, trackEvent } = useMonitoring();
const handleClick = () => {
try {
// 业务逻辑
} catch (error) {
captureError(error, { action: 'button_click' });
}
};
return <button onClick={handleClick}>Click me</button>;
}🔌 Webpack 插件
插件功能
- 自动收集构建生成的 sourcemap 文件
- 智能识别文件 hash 和映射关系
- 批量上传到后端服务器
- 支持重试和错误处理
- 构建后自动清理本地 sourcemap
高级配置
// webpack.config.js
const MiniSentryWebpackPlugin = require('mini-sentry-sdk/webpack-plugin');
module.exports = {
plugins: [
new MiniSentryWebpackPlugin({
// 基础配置
projectId: process.env.SENTRY_PROJECT_ID,
apiUrl: process.env.SENTRY_API_URL,
apiKey: process.env.SENTRY_API_KEY,
// 环境控制
enabled: process.env.NODE_ENV === 'production',
uploadInDev: false,
// 文件过滤
include: [
'**/*.map',
'!**/*vendor*.map' // 排除第三方库
],
exclude: [
'**/node_modules/**',
'**/test/**'
],
// 上传配置
timeout: 60000, // 1分钟超时
retries: 5, // 5次重试
deleteAfterUpload: true,
// 调试
debug: process.env.NODE_ENV === 'development'
})
]
};📚 API 参考
Monitor 类
构造函数
new Monitor(config: MonitorConfig)主要方法
init(): Promise
- 初始化监控
- 启动所有监控模块
captureError(error: Error, tags?: Record<string, any>): void
- 手动上报错误
error: Error 对象tags: 自定义标签
trackEvent(category, message, data?): void
- 追踪用户事件
category: 事件类别message: 事件描述data: 事件数据
trackMetric(name: string, value: number, tags?): void
- 追踪性能指标
name: 指标名称value: 指标值tags: 标签
trackBusiness(event: string, data?): void
- 追踪业务事件
event: 事件名称data: 事件数据
addBreadcrumb(category, message, level?, data?, captureType?): void
- 添加面包屑
category: 类别message: 消息level: 级别 ('info' | 'warning' | 'error')data: 附加数据captureType: 捕获类型 ('auto' | 'manual')
调试方法
getStatus(): object
- 获取监控状态
getVitalsStatus(): object
- 获取性能指标状态
getBreadcrumbStatus(): object
- 获取面包屑状态
debugLcpSituation(): void
- 调试 LCP 问题
debugErrorMapping(): void
- 调试错误映射
destroy(): void
- 销毁监控实例
ErrorBoundary 组件
Props
interface Props {
children: ReactNode;
projectId: string;
fallback?: ReactNode;
onError?: (error: ErrorInfo) => void;
tags?: Record<string, any>;
}SourceMapUploader 类
构造函数
new SourceMapUploader(config: UploaderConfig)方法
upload(request: UploadRequest): Promise
- 上传 sourcemap 文件
validateSourceMap(content: string): boolean
- 验证 sourcemap 文件格式
compressSourceMap(content: string): string
- 压缩 sourcemap 内容
💡 最佳实践
1. 环境配置
// config/monitoring.js
const isDevelopment = process.env.NODE_ENV === 'development';
const isProduction = process.env.NODE_ENV === 'production';
export const monitorConfig = {
projectId: process.env.REACT_APP_PROJECT_ID,
apiUrl: process.env.REACT_APP_MONITOR_API,
debug: isDevelopment,
sampleRate: isProduction ? 0.1 : 1, // 生产环境采样
enabledModules: {
error: true,
performance: true,
behavior: !isDevelopment // 开发环境关闭行为追踪
}
};2. 错误分类
// 添加错误分类标签
monitor.captureError(error, {
errorType: 'api_error',
module: 'user_management',
severity: 'high',
userId: getCurrentUserId()
});3. 性能监控
// 监控关键业务流程
const startTime = performance.now();
try {
await criticalBusinessFunction();
monitor.trackMetric('business_operation_duration',
performance.now() - startTime,
{ operation: 'user_registration' }
);
} catch (error) {
monitor.captureError(error, {
operation: 'user_registration',
duration: performance.now() - startTime
});
}4. 批量数据处理
// 避免频繁上报,使用防抖
import { debounce } from 'lodash';
const debouncedTrack = debounce((data) => {
monitor.trackEvent('user', 'bulk_action', data);
}, 1000);
// 批量操作时调用
items.forEach(item => {
processItem(item);
debouncedTrack({ itemId: item.id });
});5. 安全和隐私
// 清理敏感数据
monitor.captureError(error, {
userId: hashUserId(user.id), // 不直接传递用户ID
// 不包含密码、token等敏感信息
action: 'login_attempt'
});🔧 故障排除
常见问题
1. SDK 初始化失败
// 检查配置
console.log('Monitor config:', {
projectId: config.projectId,
apiUrl: config.apiUrl,
// 不要打印敏感信息如 apiKey
});
// 检查网络连接
fetch(config.apiUrl + '/health')
.then(response => console.log('API 可用:', response.status))
.catch(error => console.error('API 不可用:', error));2. SourceMap 上传失败
# 检查文件权限
ls -la dist/*.map
# 检查 API 密钥
curl -H "Authorization: Bearer YOUR_API_KEY" YOUR_API_URL/health3. 性能指标不准确
// 调试性能指标
monitor.debugLcpSituation();
console.log('Vitals status:', monitor.getVitalsStatus());
// 检查 Performance API 支持
console.log('Performance API support:', {
performance: typeof performance !== 'undefined',
observer: typeof PerformanceObserver !== 'undefined',
paintTiming: 'PerformancePaintTiming' in window
});4. 错误上报过多
// 调整采样率
const monitor = new Monitor({
sampleRate: 0.1, // 只采样 10%
maxBreadcrumbs: 5 // 减少面包屑数量
});
// 过滤特定错误
monitor.captureError = ((originalMethod) => {
return function(error, tags) {
// 过滤第三方库错误
if (error.stack && error.stack.includes('node_modules')) {
return;
}
return originalMethod.call(this, error, tags);
};
})(monitor.captureError.bind(monitor));调试技巧
启用调试模式:
const monitor = new Monitor({
projectId: 'PROJ-123456',
apiUrl: 'https://your-api.com',
debug: true // 启用详细日志
});检查上报状态:
// 查看发送状态
console.log('Send status:', monitor.getSendStatus());
// 查看面包屑状态
console.log('Breadcrumb status:', monitor.getBreadcrumbStatus());
// 重置发送状态(如果遇到问题)
monitor.resetSendStatus();网络问题诊断:
// 检查 sendBeacon 支持
console.log('sendBeacon support:', typeof navigator.sendBeacon !== 'undefined');
// 手动测试上报接口
fetch('https://your-api.com/error', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify([{ test: 'data' }])
})
.then(response => console.log('API test:', response.status))
.catch(error => console.error('API test failed:', error));📞 技术支持
如果遇到问题:
- 查看控制台错误信息
- 启用 debug 模式获取详细日志
- 检查网络连接和 API 配置
- 确认浏览器兼容性
- 参考本文档的故障排除部分
📄 许可证
MIT License
版本信息: v1.1.43
更新时间: 2025年
兼容性: 现代浏览器、Node.js 14+
🚀 实际项目示例
完整的 Vite + React 项目配置
基于真实项目的最佳实践配置,这是一个可直接运行的完整示例。
项目结构
mini-sentry-test/
├── src/
│ ├── main.tsx # SDK 初始化
│ ├── App.tsx # 主应用 + ErrorBoundary
│ └── components/
│ ├── ErrorTest.tsx # 错误测试页面
│ ├── PerformanceTest.tsx # 性能测试页面
│ └── BehaviorTest.tsx # 行为测试页面
├── plugins/
│ └── vite-mini-sentry-plugin.js # Vite 插件
├── vite.config.ts # Vite 配置
├── .env # 环境变量
└── package.json1. 环境配置
# .env
VITE_PROJECT_ID=1
VITE_API_URL=http://your-api-server.com/frontend
VITE_SOURCEMAP_URL=http://your-api-server.com/sourcemap
VITE_SDK_DEBUG=true2. Vite 配置
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
const { miniSentryVitePlugin } = require('./plugins/vite-mini-sentry-plugin.js')
export default defineConfig({
plugins: [
react(),
miniSentryVitePlugin({
projectId: process.env.VITE_PROJECT_ID,
apiUrl: process.env.VITE_SOURCEMAP_URL,
apiKey: 'your-api-key',
enabled: true,
debug: true,
include: ['assets/*.js.map'],
exclude: ['assets/vendor*.js.map']
})
],
build: {
sourcemap: true, // 🔥 关键:生产环境生成 sourcemap
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom', 'react-router-dom']
}
}
}
}
})3. SDK 初始化
// src/main.tsx
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
async function initSDK() {
try {
const { Monitor } = await import('mini-sentry-sdk');
const monitor = new Monitor({
projectId: import.meta.env.VITE_PROJECT_ID,
apiUrl: import.meta.env.VITE_API_URL,
debug: import.meta.env.VITE_SDK_DEBUG === 'true',
sampleRate: 1,
maxBreadcrumbs: 20,
defaultTags: {
environment: import.meta.env.MODE,
version: '1.0.0',
buildTime: new Date().toISOString()
},
enabledModules: {
error: true,
performance: true,
behavior: true
}
});
await monitor.init();
console.log('✅ SDK 初始化成功');
// 挂载到全局供调试使用
(window as any).monitor = monitor;
} catch (error) {
console.error('❌ SDK 初始化失败:', error);
}
}
initSDK();
const container = document.getElementById('root')!;
const root = createRoot(container);
root.render(<App />);4. React ErrorBoundary 集成
// src/App.tsx
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
class SimpleErrorBoundary extends React.Component<
{ children: React.ReactNode },
{ hasError: boolean }
> {
constructor(props: any) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(): { hasError: boolean } {
return { hasError: true };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
console.error('ErrorBoundary 捕获到错误:', error, errorInfo);
// 自动上报到 SDK
if ((window as any).monitor) {
(window as any).monitor.captureError(error, {
component: 'ErrorBoundary',
errorInfo: errorInfo.componentStack
});
}
}
render() {
if (this.state.hasError) {
return (
<div style={{ padding: '20px', textAlign: 'center' }}>
<h2>⚠️ 页面出现错误</h2>
<p>我们已经自动记录了这个问题</p>
<button onClick={() => window.location.reload()}>
🔄 刷新页面
</button>
</div>
);
}
return this.props.children;
}
}
function App() {
return (
<SimpleErrorBoundary>
<Router>
{/* 您的应用路由 */}
</Router>
</SimpleErrorBoundary>
);
}
export default App;5. 构建和部署
# 开发环境
npm run dev
# 构建(自动上传 SourceMap)
npm run build
# 验证 SourceMap 生成
npm run verify-sourcemap6. 测试验证
项目包含完整的测试页面:
- 错误测试:
/error-test- 测试各种错误捕获 - 性能测试:
/performance-test- 测试性能指标收集 - 行为测试:
/behavior-test- 测试用户行为追踪
7. 实际业务场景
// 购物车组件示例
const ShoppingCart = () => {
const handleCheckout = async () => {
try {
// 业务逻辑
await processPayment();
// 成功后追踪
(window as any).monitor?.trackBusiness('purchase_completed', {
orderId: 'ORDER-123',
amount: 99.99
});
} catch (error) {
// 自动捕获错误
(window as any).monitor?.captureError(error, {
module: 'payment',
action: 'checkout'
});
}
};
return (
<button onClick={handleCheckout}>
立即支付
</button>
);
};🎯 关键优势
- 零配置启动:克隆即可运行
- 生产级配置:包含完整的构建和部署流程
- 实战场景:模拟真实的电商、仪表板等业务场景
- 完整测试:涵盖所有SDK功能的测试用例
- 开箱即用:包含 Mock 服务器和环境配置
这个示例展示了如何在真实项目中集成 Mini-Sentry SDK,比文档中的简单示例更加实用和完整。
