mcpField
S
sentry

sentry

github.com/julianobarbosa开发1454 次安装3 天前更新
代码仓库

关于 sentry

sentry 是面向应用开发与运维人员的错误监控、性能跟踪和可观测性操作指南。它涵盖 SDK 配置、事件与追踪、CLI、API、告警和自托管部署。

主要功能

  1. 01多语言 SDK 配置示例
  2. 02捕获错误并附加上下文
  3. 03性能监控与分布式追踪
  4. 04CLI 发布及 Source Maps 管理
  5. 05API 查询问题与事件
  6. 06告警配置和自托管部署

适用场景

  1. 01为应用接入错误事件采集
  2. 02排查跨服务请求的性能问题
  3. 03在发布流程中上传 Source Maps
  4. 04通过 API 查询或批量解决问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/julianobarbosa/claude-code-skills --skill sentry

安装后在 Claude Code 中输入/sentry确认已加载。

详细介绍

Sentry 技能

使用 Sentry 进行错误监控、性能跟踪和应用可观测性的综合指南。

快速参考

DSN(数据源名称)

DSN 是 Sentry 项目的唯一标识符:

https://<PUBLIC_KEY>@<HOST>/<PROJECT_ID>

示例:https://[email protected]/1234567

核心概念
概念描述
事件发送到 Sentry 的单个数据实例(错误、事务等)
问题根据指纹去重后的一组相似事件
事务表示一个工作单元的性能监控跨度
Span事务中的单个操作(数据库查询、HTTP 调用)
Trace跨服务连接的一系列事务
发布版本部署到某个环境的代码版本
环境部署目标(生产、预发布、开发)

SDK 安装与配置

JavaScript/Node.js
npm install @sentry/node @sentry/profiling-node
const Sentry = require("@sentry/node");
const { nodeProfilingIntegration } = require("@sentry/profiling-node");

Sentry.init({
  dsn: "https://[email protected]/1",
  release: process.env.RELEASE_VERSION || "1.0.0",
  environment: process.env.NODE_ENV || "development",

  // Error sampling (1.0 = 100% of errors)
  sampleRate: 1.0,

  // Performance monitoring (0.1 = 10% of transactions)
  tracesSampleRate: 0.1,

  // OR use dynamic sampling
  tracesSampler: (samplingContext) => {
    if (samplingContext.transactionContext.name === "/health") {
      return 0; // Don't sample health checks
    }
    if (samplingContext.parentSampled !== undefined) {
      return samplingContext.parentSampled; // Inherit parent decision
    }
    return 0.1; // Default 10%
  },

  // Profiling
  profilesSampleRate: 0.1,
  integrations: [nodeProfilingIntegration()],

  // Data scrubbing
  beforeSend(event) {
    if (event.request?.headers) {
      delete event.request.headers["Authorization"];
    }
    return event;
  },
});
Python
pip install sentry-sdk
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration

sentry_sdk.init(
    dsn="https://[email protected]/1",
    release="[email protected]",
    environment="production",

    # Error sampling
    sample_rate=1.0,

    # Performance monitoring
    traces_sample_rate=0.1,

    # OR dynamic sampling
    traces_sampler=lambda ctx: (
        0 if ctx.get("transaction_context", {}).get("name") == "/health"
        else 0.1
    ),

    # Profiling
    profiles_sample_rate=0.1,

    # Integrations
    integrations=[
        FlaskIntegration(),
        SqlalchemyIntegration(),
    ],

    # Data scrubbing
    before_send=lambda event, hint: scrub_sensitive_data(event),
)

def scrub_sensitive_data(event):
    if event.get("request", {}).get("headers"):
        event["request"]["headers"].pop("Authorization", None)
    return event
Go
go get github.com/getsentry/sentry-go
package main

import (
    "log"
    "time"
    "github.com/getsentry/sentry-go"
)

func main() {
    err := sentry.Init(sentry.ClientOptions{
        Dsn:              "https://[email protected]/1",
        Release:          "[email protected]",
        Environment:      "production",
        TracesSampleRate: 0.1,
        BeforeSend: func(event *sentry.Event, hint *sentry.EventHint) *sentry.Event {
            // Scrub sensitive data
            return event
        },
    })
    if err != nil {
        log.Fatalf("sentry.Init: %s", err)
    }
    defer sentry.Flush(2 * time.Second)
}

错误捕获

手动捕获错误
// JavaScript
try {
  riskyOperation();
} catch (error) {
  Sentry.captureException(error, {
    tags: { component: "payment" },
    extra: { orderId: "12345" },
    user: { id: "user-123", email: "[email protected]" },
  });
}

// Capture message
Sentry.captureMessage("Something unexpected happened", "warning");
# Python
try:
    risky_operation()
except Exception as e:
    sentry_sdk.capture_exception(e)
    sentry_sdk.set_tag("component", "payment")
    sentry_sdk.set_extra("order_id", "12345")
    sentry_sdk.set_user({"id": "user-123", "email": "[email protected]"})

# Capture message
sentry_sdk.capture_message("Something unexpected happened", level="warning")
面包屑
// Add context breadcrumbs
Sentry.addBreadcrumb({
  category: "auth",
  message: "User logged in",
  level: "info",
  data: { userId: "123" },
});
作用域
// Configure scope for context
Sentry.configureScope((scope) => {
  scope.setUser({ id: "user-123" });
  scope.setTag("page_locale", "en-US");
  scope.setExtra("session_data", { cart_items: 5 });
});

// Isolated scope
Sentry.withScope((scope) => {
  scope.setTag("isolated", "true");
  Sentry.captureException(new Error("Scoped error"));
});

性能监控

手动创建事务
const transaction = Sentry.startTransaction({
  op: "task",
  name: "Process Order",
});

// Set transaction on scope
Sentry.getCurrentHub().configureScope((scope) => {
  scope.setSpan(transaction);
});

// Create child spans
const span = transaction.startChild({
  op: "db.query",
  description: "SELECT * FROM orders",
});

// Do work...
await queryDatabase();

span.finish();
transaction.finish();
分布式追踪
// Service A - Create trace
const transaction = Sentry.startTransaction({ name: "API Request" });
const traceHeader = transaction.toTraceparent();
// Pass traceHeader to Service B via HTTP header: sentry-trace

// Service B - Continue trace
const incomingTrace = request.headers["sentry-trace"];
const transaction = Sentry.startTransaction({
  name: "Process Request",
  op: "http.server",
}, { parentSampled: true });

Sentry CLI

安装
# npm
npm install -g @sentry/cli

# curl
curl -sL https://sentry.io/get-cli/ | bash

# Homebrew
brew install getsentry/tools/sentry-cli
身份验证
# Login interactively
sentry-cli login

# Or set auth token
export SENTRY_AUTH_TOKEN=your-token
export SENTRY_ORG=your-org
export SENTRY_PROJECT=your-project
发布版本管理
# Create release
sentry-cli releases new v1.0.0

# Associate commits (auto-detect from git)
sentry-cli releases set-commits v1.0.0 --auto

# Or specify commit range
sentry-cli releases set-commits v1.0.0 --commit "repo@from_sha..to_sha"

# Upload source maps
sentry-cli releases files v1.0.0 upload-sourcemaps ./dist \
  --url-prefix '~/static/js' \
  --rewrite

# Upload debug symbols (iOS/Android/Native)
sentry-cli debug-files upload --include-sources path/to/symbols

# Deploy release to environment
sentry-cli releases deploys v1.0.0 new -e production

# Finalize release
sentry-cli releases finalize v1.0.0
Source Maps 工作流
# Build with source maps
npm run build

# Create release and upload
export VERSION=$(sentry-cli releases propose-version)
sentry-cli releases new $VERSION
sentry-cli releases files $VERSION upload-sourcemaps ./dist \
  --url-prefix '~/' \
  --validate
sentry-cli releases finalize $VERSION
Cron 监控
# Wrap a cron job
sentry-cli monitors run <monitor-slug> -- /path/to/script.sh

# Or use check-in API
sentry-cli monitors run <monitor-slug> --check-in-status in_progress
# ... run job ...
sentry-cli monitors run <monitor-slug> --check-in-status ok
发送测试事件
sentry-cli send-event -m "Test event from CLI"

API 参考

身份验证
# Bearer token (recommended)
curl -H "Authorization: Bearer <AUTH_TOKEN>" \
  https://sentry.io/api/0/projects/

# DSN-based (limited endpoints)
curl -u <PUBLIC_KEY>: \
  https://sentry.io/api/<PROJECT_ID>/store/
常用端点
端点方法描述
/api/0/organizations/GET列出组织
/api/0/organizations/{org}/projects/GET列出项目
/api/0/projects/{org}/{project}/issues/GET列出问题
/api/0/organizations/{org}/issues/{issue_id}/GET获取问题详情
/api/0/projects/{org}/{project}/events/GET列出事件
/api/0/organizations/{org}/releases/GET/POST列出/创建发布版本
/api/0/projects/{org}/{project}/keys/GET列出 DSN 密钥
查询问题
# List issues with filters
curl -H "Authorization: Bearer $TOKEN" \
  "https://sentry.io/api/0/projects/{org}/{project}/issues/?query=is:unresolved+level:error&statsPeriod=24h"

# Get issue details
curl -H "Authorization: Bearer $TOKEN" \
  "https://sentry.io/api/0/organizations/{org}/issues/{issue_id}/"

# Resolve issue
curl -X PUT -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "resolved"}' \
  "https://sentry.io/api/0/organizations/{org}/issues/{issue_id}/"
通过 API 创建发布版本
curl -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "v1.0.0",
    "projects": ["my-project"],
    "refs": [{
      "repository": "org/repo",
      "commit": "abc123"
    }]
  }' \
  "https://sentry.io/api/0/organizations/{org}/releases/"
分页
# Response includes Link header
Link: <https://sentry.io/api/0/...?cursor=123:0:0>; rel="previous"; results="false",
      <https://sentry.io/api/0/...?cursor=456:0:0>; rel="next"; results="true"
速率限制
  • 默认:大多数端点每秒 40 个请求
  • 批量端点:限制较低
  • 标头:X-Sentry-Rate-Limit-Remaining、X-Sentry-Rate-Limit-Reset

警报配置

问题警报(通过 UI/API)
{
  "name": "High Error Rate Alert",
  "conditions": [
    {
      "id": "sentry.rules.conditions.event_frequency.EventFrequencyCondition",
      "interval": "1h",
      "value": 100
    }
  ],
  "actions": [
    {
      "id": "sentry.integrations.slack.notify_action.SlackNotifyServiceAction",
      "channel": "#alerts",
      "workspace": "workspace-id"
    }
  ],
  "actionMatch": "all",
  "filterMatch": "all",
  "frequency": 30
}
指标警报
# Example: Alert on error rate > 5%
triggers:
  - alertThreshold: 5
    label: critical
    actions:
      - type: slack
        channel: "#critical-alerts"
  - alertThreshold: 2
    label: warning
    actions:
      - type: email
        targetIdentifier: "[email protected]"

OpenTelemetry 集成

导出 OTLP 到 Sentry
const { NodeSDK } = require("@opentelemetry/sdk-node");
const { OTLPTraceExporter } = require("@opentelemetry/exporter-trace-otlp-http");

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: "https://sentry.io/api/<PROJECT_ID>/envelope/",
    headers: {
      "sentry-trace": "...",
    },
  }),
});

sdk.start();
将 Sentry 与 OpenTelemetry 配合使用
const Sentry = require("@sentry/node");

Sentry.init({
  dsn: "...",
  instrumenter: "otel", // Use OpenTelemetry for instrumentation
  tracesSampleRate: 0.1,
});

自托管部署

系统要求
资源最低要求建议配置
CPU4 核8 核以上
RAM16 GB32 GB 以上
交换空间16 GB-
磁盘100 GB SSD500 GB SSD 以上
Docker19.03+最新版本
Docker Compose2.19+最新版本
安装
# Clone repository
VERSION=$(curl -Ls -o /dev/null -w %{url_effective} \
  https://github.com/getsentry/self-hosted/releases/latest)
VERSION=${VERSION##*/}

git clone https://github.com/getsentry/self-hosted.git
cd self-hosted
git checkout ${VERSION}

# Run installer
./install.sh

# Start services
docker compose up -d

# Access at http://localhost:9000
配置(sentry/config.yml)
# Mail
mail.backend: 'smtp'
mail.host: 'smtp.example.com'
mail.port: 587
mail.username: '[email protected]'
mail.password: 'password'
mail.use-tls: true
mail.from: '[email protected]'

# System
system.url-prefix: 'https://sentry.example.com'
system.secret-key: 'your-secret-key'

# Features
features.organizations:early-adopter: False
外部存储(GCS/S3)
# sentry/config.yml
filestore.backend: 'gcs'
filestore.options:
  bucket_name: 'sentry-files'

# Or S3
filestore.backend: 's3'
filestore.options:
  access_key: 'AWS_ACCESS_KEY'
  secret_key: 'AWS_SECRET_KEY'
  bucket_name: 'sentry-files'
  region_name: 'us-east-1'
外部数据库
# PostgreSQL
SENTRY_POSTGRES_HOST: 'postgres.example.com'
SENTRY_POSTGRES_PORT: '5432'
SENTRY_DB_NAME: 'sentry'
SENTRY_DB_USER: 'sentry'
SENTRY_DB_PASSWORD: 'password'

# Redis
SENTRY_REDIS_HOST: 'redis.example.com'
SENTRY_REDIS_PORT: '6379'

# Kafka
SENTRY_KAFKA_HOST: 'kafka.example.com:9092'
扩展 Worker
# Scale specific services
docker compose up -d --scale worker=4 --scale snuba-consumer=2
监控自托管部署
# Enable StatsD metrics
SENTRY_METRICS_BACKEND: 'statsd'
SENTRY_METRICS_OPTIONS:
  host: 'statsd.example.com'
  port: 8125

最佳实践

采样策略
// Dynamic sampling based on context
tracesSampler: (ctx) => {
  // Always sample errors
  if (ctx.transactionContext.name.includes("error")) return 1.0;

  // Lower rate for high-volume endpoints
  if (ctx.transactionContext.name === "/api/health") return 0;
  if (ctx.transactionContext.name.startsWith("/api/v1/")) return 0.05;

  // Default rate
  return 0.1;
}
数据清理
beforeSend(event) {
  // Remove PII
  if (event.user) {
    delete event.user.email;
    delete event.user.ip_address;
  }

  // Scrub sensitive headers
  if (event.request?.headers) {
    delete event.request.headers["Authorization"];
    delete event.request.headers["Cookie"];
  }

  // Filter local errors in production
  if (event.exception?.values?.[0]?.type === "ChunkLoadError") {
    return null; // Drop event
  }

  return event;
}
发布版本跟踪
# CI/CD Pipeline Example
export SENTRY_RELEASE=$(git rev-parse --short HEAD)

# Before deploy
sentry-cli releases new $SENTRY_RELEASE
sentry-cli releases set-commits $SENTRY_RELEASE --auto
sentry-cli releases files $SENTRY_RELEASE upload-sourcemaps ./dist

# After deploy
sentry-cli releases deploys $SENTRY_RELEASE new -e production
sentry-cli releases finalize $SENTRY_RELEASE
配额管理
// Client-side rate limiting
Sentry.init({
  dsn: "...",
  maxBreadcrumbs: 50,
  maxValueLength: 1000,

  // Limit events per session
  beforeSend(event, hint) {
    if (sessionEventCount++ > 100) {
      return null; // Drop after 100 events
    }
    return event;
  }
});

常见操作

调试集成问题
# Enable debug mode
Sentry.init({ debug: true });

# Test event delivery
sentry-cli send-event -m "Test message"

# Verify source maps
sentry-cli releases files <release> list
sentry-cli sourcemaps explain <event-id>
批量解决问题
# Via API
curl -X PUT -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status": "resolved"}' \
  "https://sentry.io/api/0/projects/{org}/{project}/issues/?id=123&id=456"
导出事件
# Query events via Discover
curl -H "Authorization: Bearer $TOKEN" \
  "https://sentry.io/api/0/organizations/{org}/events/?field=title&field=count()&query=event.type:error&statsPeriod=7d"

故障排查

问题解决方案
未显示事件检查 DSN,确认网络连接正常,启用 debug: true
Source Maps 无法正常工作确认发布版本匹配,检查 URL 前缀,使用 sourcemaps explain
事件量过大实施采样,使用 beforeSend 进行筛选
性能开销过高降低 tracesSampleRate,禁用不必要的集成
自托管 OOM增加内存,添加交换空间,进行水平扩展

参考文档


注意事项

  • traces_sample_rate=1.0 和事务筛选回调:回调会在采样后运行。100% 采样并使用丢弃 99% 事务的筛选器,会将 99% 的采样预算浪费在随后被丢弃的事务上。
  • 生产环境 JS 的源映射:源映射版本缺失或有误会导致堆栈跟踪被混淆;请使用 sentry-cli sourcemaps explain 验证。
  • 通过环境变量跟踪版本不可靠——请在 CI 中显式调用 sentry-cli releases new $VERSION && deploys new。
  • 性能监控和错误监控使用独立的采样和配额——耗尽性能监控配额不会影响错误监控,反之亦然,但可能出现意外的账单。
  • DSN 暴露:客户端 DSN 可公开;带有身份验证权限范围的服务端 DSN 绝不能出现在客户端代码中(而且 CLI 不会对此进行强制检查)。
  • before_send 钩子会丢弃或修改事件:有缺陷的钩子可能会悄无声息地丢失错误。部署前请使用模拟异常测试钩子。

评论

支持 Markdown