error-tracking

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Error Tracking

错误追踪

Overview

概述

Set up comprehensive error tracking with Sentry to automatically capture, report, and analyze exceptions, performance issues, and application stability.
通过Sentry搭建全面的错误追踪体系,自动捕获、上报并分析异常、性能问题以及应用稳定性情况。

When to Use

适用场景

  • Production error monitoring
  • Automatic exception capture
  • Release tracking
  • Performance issue detection
  • User impact analysis
  • 生产环境错误监控
  • 自动异常捕获
  • 版本发布追踪
  • 性能问题检测
  • 用户影响分析

Instructions

操作步骤

1. Sentry Setup

1. Sentry 环境搭建

bash
npm install -g @sentry/cli
npm install @sentry/node @sentry/tracing
sentry init -d
bash
npm install -g @sentry/cli
npm install @sentry/node @sentry/tracing
sentry init -d

2. Node.js Sentry Integration

2. Node.js 集成 Sentry

javascript
// sentry.js
const Sentry = require("@sentry/node");
const Tracing = require("@sentry/tracing");

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV || 'development',
  tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
  release: process.env.APP_VERSION || '1.0.0',
  integrations: [
    new Sentry.Integrations.Http({ tracing: true }),
    new Tracing.Integrations.Express({
      app: true,
      request: true,
      transaction: true
    })
  ],
  ignoreErrors: [
    'Network request failed',
    'TimeoutError'
  ]
});

module.exports = Sentry;
javascript
// sentry.js
const Sentry = require("@sentry/node");
const Tracing = require("@sentry/tracing");

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV || 'development',
  tracesSampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
  release: process.env.APP_VERSION || '1.0.0',
  integrations: [
    new Sentry.Integrations.Http({ tracing: true }),
    new Tracing.Integrations.Express({
      app: true,
      request: true,
      transaction: true
    })
  ],
  ignoreErrors: [
    'Network request failed',
    'TimeoutError'
  ]
});

module.exports = Sentry;

3. Express Middleware Integration

3. Express 中间件集成

javascript
// app.js
const express = require('express');
const Sentry = require('./sentry');

const app = express();

app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.tracingHandler());

app.get('/api/users/:id', (req, res) => {
  const transaction = Sentry.startTransaction({
    name: 'get_user',
    op: 'http.server'
  });

  try {
    const userId = req.params.id;

    Sentry.captureMessage('Fetching user', {
      level: 'info',
      tags: { userId: userId }
    });

    const user = db.query(`SELECT * FROM users WHERE id = ${userId}`);

    if (!user) {
      Sentry.captureException(new Error('User not found'), {
        level: 'warning',
        contexts: { request: { userId } }
      });
      return res.status(404).json({ error: 'User not found' });
    }

    transaction.setTag('user.id', user.id);
    res.json(user);
  } catch (error) {
    Sentry.captureException(error, {
      level: 'error',
      tags: { endpoint: 'get_user', userId: req.params.id }
    });
    res.status(500).json({ error: 'Internal server error' });
  } finally {
    transaction.finish();
  }
});

app.use(Sentry.Handlers.errorHandler());

app.listen(3000);
javascript
// app.js
const express = require('express');
const Sentry = require('./sentry');

const app = express();

app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.tracingHandler());

app.get('/api/users/:id', (req, res) => {
  const transaction = Sentry.startTransaction({
    name: 'get_user',
    op: 'http.server'
  });

  try {
    const userId = req.params.id;

    Sentry.captureMessage('Fetching user', {
      level: 'info',
      tags: { userId: userId }
    });

    const user = db.query(`SELECT * FROM users WHERE id = ${userId}`);

    if (!user) {
      Sentry.captureException(new Error('User not found'), {
        level: 'warning',
        contexts: { request: { userId } }
      });
      return res.status(404).json({ error: 'User not found' });
    }

    transaction.setTag('user.id', user.id);
    res.json(user);
  } catch (error) {
    Sentry.captureException(error, {
      level: 'error',
      tags: { endpoint: 'get_user', userId: req.params.id }
    });
    res.status(500).json({ error: 'Internal server error' });
  } finally {
    transaction.finish();
  }
});

app.use(Sentry.Handlers.errorHandler());

app.listen(3000);

4. Python Sentry Integration

4. Python 集成 Sentry

python
undefined
python
undefined

sentry_config.py

sentry_config.py

import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration from sentry_sdk.integrations.logging import LoggingIntegration import logging import os
sentry_logging = LoggingIntegration( level=logging.INFO, event_level=logging.ERROR )
sentry_sdk.init( dsn=os.environ.get('SENTRY_DSN'), integrations=[FlaskIntegration(), sentry_logging], environment=os.environ.get('ENVIRONMENT', 'development'), release=os.environ.get('APP_VERSION', '1.0.0'), traces_sample_rate=0.1 if os.environ.get('ENVIRONMENT') == 'production' else 1.0, attach_stacktrace=True )
import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration from sentry_sdk.integrations.logging import LoggingIntegration import logging import os
sentry_logging = LoggingIntegration( level=logging.INFO, event_level=logging.ERROR )
sentry_sdk.init( dsn=os.environ.get('SENTRY_DSN'), integrations=[FlaskIntegration(), sentry_logging], environment=os.environ.get('ENVIRONMENT', 'development'), release=os.environ.get('APP_VERSION', '1.0.0'), traces_sample_rate=0.1 if os.environ.get('ENVIRONMENT') == 'production' else 1.0, attach_stacktrace=True )

Flask integration

Flask integration

from flask import Flask import sentry_sdk
app = Flask(name)
@app.route('/api/orders/<order_id>') def get_order(order_id): try: sentry_sdk.set_user({'id': request.user.id}) sentry_sdk.capture_message(f'Fetching order {order_id}', level='info')
    order = db.query(f'SELECT * FROM orders WHERE id = {order_id}')

    if not order:
        sentry_sdk.capture_exception(ValueError('Order not found'))
        return {'error': 'Order not found'}, 404

    return {'order': order}

except Exception as e:
    sentry_sdk.capture_exception(e, {
        'tags': { 'endpoint': 'get_order', 'order_id': order_id }
    })
    return {'error': 'Internal server error'}, 500
undefined
from flask import Flask import sentry_sdk
app = Flask(name)
@app.route('/api/orders/<order_id>') def get_order(order_id): try: sentry_sdk.set_user({'id': request.user.id}) sentry_sdk.capture_message(f'Fetching order {order_id}', level='info')
    order = db.query(f'SELECT * FROM orders WHERE id = {order_id}')

    if not order:
        sentry_sdk.capture_exception(ValueError('Order not found'))
        return {'error': 'Order not found'}, 404

    return {'order': order}

except Exception as e:
    sentry_sdk.capture_exception(e, {
        'tags': { 'endpoint': 'get_order', 'order_id': order_id }
    })
    return {'error': 'Internal server error'}, 500
undefined

5. Source Maps and Release Management

5. Source Maps 与版本发布管理

javascript
// webpack.config.js
const SentryCliPlugin = require('@sentry/webpack-plugin');

module.exports = {
  plugins: [
    new SentryCliPlugin({
      include: './dist',
      urlPrefix: 'https://example.com/',
      release: process.env.APP_VERSION || '1.0.0',
      org: process.env.SENTRY_ORG,
      project: process.env.SENTRY_PROJECT,
      authToken: process.env.SENTRY_AUTH_TOKEN
    })
  ]
};
javascript
// webpack.config.js
const SentryCliPlugin = require('@sentry/webpack-plugin');

module.exports = {
  plugins: [
    new SentryCliPlugin({
      include: './dist',
      urlPrefix: 'https://example.com/',
      release: process.env.APP_VERSION || '1.0.0',
      org: process.env.SENTRY_ORG,
      project: process.env.SENTRY_PROJECT,
      authToken: process.env.SENTRY_AUTH_TOKEN
    })
  ]
};

6. CI/CD Release Creation

6. CI/CD 版本发布配置

bash
#!/bin/bash
VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g')
bash
#!/bin/bash
VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[",]//g')

Create release

Create release

sentry-cli releases -o my-org -p my-project create $VERSION
sentry-cli releases -o my-org -p my-project create $VERSION

Upload source maps

Upload source maps

sentry-cli releases -o my-org -p my-project files $VERSION upload-sourcemaps ./dist
sentry-cli releases -o my-org -p my-project files $VERSION upload-sourcemaps ./dist

Finalize release

Finalize release

sentry-cli releases -o my-org -p my-project finalize $VERSION
sentry-cli releases -o my-org -p my-project finalize $VERSION

Deploy

Deploy

sentry-cli releases -o my-org -p my-project deploys $VERSION new -e production
undefined
sentry-cli releases -o my-org -p my-project deploys $VERSION new -e production
undefined

7. Custom Error Context

7. 自定义错误上下文

javascript
// custom-error-context.js
const Sentry = require('@sentry/node');

Sentry.configureScope(scope => {
  scope.setUser({
    id: userId,
    email: userEmail,
    subscription: 'pro'
  });

  scope.setTag('feature_flag', 'new-ui');
  scope.setTag('database', 'postgres-v12');

  scope.setContext('character', {
    name: 'Mighty Fighter',
    level: 19
  });

  scope.addBreadcrumb({
    category: 'ui.click',
    message: 'User clicked signup button',
    level: 'info'
  });

  scope.addBreadcrumb({
    category: 'database',
    message: 'Query executed',
    level: 'debug',
    data: {
      query: 'SELECT * FROM users',
      duration: 125
    }
  });
});

// Before sending
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  beforeSend(event, hint) {
    if (event.request) {
      delete event.request.cookies;
      delete event.request.headers['authorization'];
    }
    return event;
  }
});
javascript
// custom-error-context.js
const Sentry = require('@sentry/node');

Sentry.configureScope(scope => {
  scope.setUser({
    id: userId,
    email: userEmail,
    subscription: 'pro'
  });

  scope.setTag('feature_flag', 'new-ui');
  scope.setTag('database', 'postgres-v12');

  scope.setContext('character', {
    name: 'Mighty Fighter',
    level: 19
  });

  scope.addBreadcrumb({
    category: 'ui.click',
    message: 'User clicked signup button',
    level: 'info'
  });

  scope.addBreadcrumb({
    category: 'database',
    message: 'Query executed',
    level: 'debug',
    data: {
      query: 'SELECT * FROM users',
      duration: 125
    }
  });
});

// Before sending
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  beforeSend(event, hint) {
    if (event.request) {
      delete event.request.cookies;
      delete event.request.headers['authorization'];
    }
    return event;
  }
});

8. Performance Monitoring

8. 性能监控

javascript
// performance.js
const Sentry = require('@sentry/node');

const transaction = Sentry.startTransaction({
  name: 'process_order',
  op: 'task',
  data: { orderId: '12345' }
});

const dbSpan = transaction.startChild({
  op: 'db',
  description: 'Save order to database'
});
saveOrderToDb(order);
dbSpan.finish();

const paymentSpan = transaction.startChild({
  op: 'http.client',
  description: 'Process payment'
});
processPayment(order);
paymentSpan.finish();

transaction.setStatus('ok');
transaction.finish();
javascript
// performance.js
const Sentry = require('@sentry/node');

const transaction = Sentry.startTransaction({
  name: 'process_order',
  op: 'task',
  data: { orderId: '12345' }
});

const dbSpan = transaction.startChild({
  op: 'db',
  description: 'Save order to database'
});
saveOrderToDb(order);
dbSpan.finish();

const paymentSpan = transaction.startChild({
  op: 'http.client',
  description: 'Process payment'
});
processPayment(order);
paymentSpan.finish();

transaction.setStatus('ok');
transaction.finish();

Best Practices

最佳实践

✅ DO

✅ 建议做法

  • Set up source maps for production
  • Configure appropriate sample rates
  • Track releases and deployments
  • Filter sensitive information
  • Add meaningful context to errors
  • Use breadcrumbs for debugging
  • Set user information
  • Review error patterns regularly
  • 为生产环境配置Source Maps
  • 设置合理的采样率
  • 追踪版本发布与部署信息
  • 过滤敏感信息
  • 为错误添加有意义的上下文
  • 使用Breadcrumbs辅助调试
  • 设置用户信息
  • 定期查看错误模式

❌ DON'T

❌ 禁止做法

  • Send 100% of errors in production
  • Include passwords in context
  • Ignore configuration for environment
  • Skip source map uploads
  • Log personally identifiable information
  • Use without proper filtering
  • Disable tracking in production
  • 在生产环境中上报100%的错误
  • 在上下文中包含密码信息
  • 忽略环境相关的配置
  • 跳过Source Maps上传
  • 记录个人可识别信息
  • 不做过滤直接使用
  • 在生产环境中禁用追踪

Key Commands

常用命令

bash
sentry-cli releases create $VERSION
sentry-cli releases files upload-sourcemaps $VERSION ./dist
sentry-cli releases deploys $VERSION new -e production
sentry-cli releases finalize $VERSION
sentry-cli releases info $VERSION
bash
sentry-cli releases create $VERSION
sentry-cli releases files upload-sourcemaps $VERSION ./dist
sentry-cli releases deploys $VERSION new -e production
sentry-cli releases finalize $VERSION
sentry-cli releases info $VERSION