Sentry 后端集成 #
后端集成概述 #
后端服务是应用的核心,处理业务逻辑和数据存储。Sentry 后端集成可以帮助你:
text
┌─────────────────────────────────────────────────────────────┐
│ 后端监控价值 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. 捕获服务端错误 │
│ - 未处理的异常 │
│ - 数据库错误 │
│ - 外部服务调用失败 │
│ │
│ 2. 监控 API 性能 │
│ - 请求处理时间 │
│ - 数据库查询耗时 │
│ - 外部 API 调用 │
│ │
│ 3. 分布式追踪 │
│ - 跨服务请求追踪 │
│ - 微服务调用链 │
│ - 性能瓶颈定位 │
│ │
└─────────────────────────────────────────────────────────────┘
Python 集成 #
安装 #
bash
# pip
pip install sentry-sdk
# poetry
poetry add sentry-sdk
# pipenv
pipenv install sentry-sdk
Flask 集成 #
python
# app.py
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from flask import Flask, request
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations=[FlaskIntegration()],
traces_sample_rate=0.1,
profiles_sample_rate=0.1,
environment="production",
release="my-flask-app@1.0.0",
send_default_pii=True,
)
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello, World!"
@app.route("/error")
def trigger_error():
division_by_zero = 1 / 0
return "This will not be reached"
@app.errorhandler(500)
def handle_500(error):
sentry_sdk.capture_exception(error)
return "Internal Server Error", 500
if __name__ == "__main__":
app.run()
Django 集成 #
python
# settings.py
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations=[DjangoIntegration()],
traces_sample_rate=0.1,
environment="production",
release="my-django-app@1.0.0",
send_default_pii=True,
signals_to_ignore=[
"django.db.backends.signals",
],
)
python
# views.py
from django.http import JsonResponse
import sentry_sdk
def api_view(request):
try:
result = process_data(request.GET)
return JsonResponse(result)
except Exception as error:
sentry_sdk.capture_exception(error)
return JsonResponse({"error": str(error)}, status=500)
FastAPI 集成 #
python
# main.py
import sentry_sdk
from sentry_sdk.integrations.starlette import StarletteIntegration
from sentry_sdk.integrations.fastapi import FastApiIntegration
from fastapi import FastAPI, Request
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations=[
StarletteIntegration(),
FastApiIntegration(),
],
traces_sample_rate=0.1,
environment="production",
)
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/error")
async def trigger_error():
raise Exception("This is a test error")
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
sentry_sdk.capture_exception(exc)
return {"error": str(exc)}, 500
Python 异步支持 #
python
import sentry_sdk
import asyncio
async def async_operation():
with sentry_sdk.start_transaction(
op="task",
name="async_operation",
) as transaction:
span = transaction.start_child(
op="db.query",
description="fetch_users",
)
users = await fetch_users()
span.finish()
return users
async def main():
async with sentry_sdk.Hub(sentry_sdk.Hub.current):
await async_operation()
asyncio.run(main())
Node.js 集成 #
安装 #
bash
# npm
npm install @sentry/node
# yarn
yarn add @sentry/node
Express 集成 #
javascript
// app.js
const express = require("express");
const Sentry = require("@sentry/node");
const { ProfilingIntegration } = require("@sentry/profiling-node");
const app = express();
Sentry.init({
dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations: [
new Sentry.Integrations.Http({ tracing: true }),
new Sentry.Integrations.Express({ app }),
new ProfilingIntegration(),
],
tracesSampleRate: 0.1,
profilesSampleRate: 0.1,
environment: process.env.NODE_ENV,
release: `my-express-app@${process.env.npm_package_version}`,
});
app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.tracingHandler());
app.use(express.json());
app.get("/", (req, res) => {
res.send("Hello World");
});
app.get("/error", (req, res) => {
throw new Error("This is a test error");
});
app.get("/api/users/:id", async (req, res) => {
const transaction = Sentry.startTransaction({
name: "GET /api/users/:id",
op: "http.server",
});
try {
const user = await getUserById(req.params.id);
res.json(user);
} catch (error) {
Sentry.captureException(error);
res.status(500).json({ error: error.message });
} finally {
transaction.finish();
}
});
app.use(Sentry.Handlers.errorHandler());
app.listen(3000, () => {
console.log("Server running on port 3000");
});
NestJS 集成 #
typescript
// main.ts
import { NestFactory } from "@nestjs/core";
import * as Sentry from "@sentry/node";
import { SentryFilter } from "./sentry.filter";
import { AppModule } from "./app.module";
Sentry.init({
dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations: [
new Sentry.Integrations.Http({ tracing: true }),
],
tracesSampleRate: 0.1,
environment: process.env.NODE_ENV,
});
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(Sentry.Handlers.requestHandler());
app.useGlobalFilters(new SentryFilter());
await app.listen(3000);
}
bootstrap();
typescript
// sentry.filter.ts
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
} from "@nestjs/common";
import { Request, Response } from "express";
import * as Sentry from "@sentry/node";
@Catch()
export class SentryFilter implements ExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
Sentry.withScope((scope) => {
scope.setTag("path", request.url);
scope.setExtra("body", request.body);
scope.setUser({ id: request.user?.id });
Sentry.captureException(exception);
});
const status =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;
const message =
exception instanceof HttpException
? exception.message
: "Internal server error";
response.status(status).json({
statusCode: status,
message,
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
Koa 集成 #
javascript
// app.js
const Koa = require("koa");
const Sentry = require("@sentry/node");
const app = new Koa();
Sentry.init({
dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations: [
new Sentry.Integrations.Koa({ app }),
],
tracesSampleRate: 0.1,
});
app.use(async (ctx, next) => {
try {
await next();
} catch (error) {
Sentry.withScope((scope) => {
scope.setTag("path", ctx.path);
scope.setExtra("body", ctx.request.body);
Sentry.captureException(error);
});
ctx.status = error.status || 500;
ctx.body = { error: error.message };
}
});
app.use(async (ctx) => {
ctx.body = "Hello World";
});
app.listen(3000);
Go 集成 #
安装 #
bash
go get github.com/getsentry/sentry-go
基础配置 #
go
// main.go
package main
import (
"time"
"github.com/getsentry/sentry-go"
)
func main() {
err := sentry.Init(sentry.ClientOptions{
Dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
TracesSampleRate: 0.1,
Environment: "production",
Release: "my-go-app@1.0.0",
Debug: false,
})
if err != nil {
panic(err)
}
defer sentry.Flush(2 * time.Second)
// 应用逻辑...
}
HTTP Handler 集成 #
go
// main.go
package main
import (
"net/http"
"time"
"github.com/getsentry/sentry-go"
sentryhttp "github.com/getsentry/sentry-go/http"
)
func main() {
sentry.Init(sentry.ClientOptions{
Dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
TracesSampleRate: 0.1,
})
defer sentry.Flush(2 * time.Second)
sentryHandler := sentryhttp.New(sentryhttp.Options{})
http.Handle("/", sentryHandler.HandleFunc(func(w http.ResponseWriter, r *http.Request) {
hub := sentry.GetHubFromContext(r.Context())
hub.Scope().SetTag("path", r.URL.Path)
w.Write([]byte("Hello, World!"))
}))
http.Handle("/error", sentryHandler.HandleFunc(func(w http.ResponseWriter, r *http.Request) {
panic("This is a test error")
}))
http.ListenAndServe(":8080", nil)
}
Gin 集成 #
go
// main.go
package main
import (
"time"
"github.com/getsentry/sentry-go"
sentrygin "github.com/getsentry/sentry-go/gin"
"github.com/gin-gonic/gin"
)
func main() {
sentry.Init(sentry.ClientOptions{
Dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
TracesSampleRate: 0.1,
})
defer sentry.Flush(2 * time.Second)
r := gin.Default()
r.Use(sentrygin.New(sentrygin.Options{}))
r.GET("/", func(c *gin.Context) {
c.String(200, "Hello, World!")
})
r.GET("/error", func(c *gin.Context) {
if hub := sentrygin.GetHubFromContext(c); hub != nil {
hub.WithScope(func(scope *sentry.Scope) {
scope.SetTag("path", c.Request.URL.Path)
hub.CaptureException(fmt.Errorf("test error"))
})
}
c.String(500, "Error occurred")
})
r.Run(":8080")
}
手动捕获错误 #
go
// 捕获错误
sentry.CaptureException(fmt.Errorf("something went wrong"))
// 捕获消息
sentry.CaptureMessage("Something went wrong", sentry.LevelWarning)
// 使用 Scope
sentry.WithScope(func(scope *sentry.Scope) {
scope.SetTag("category", "database")
scope.SetExtra("query", "SELECT * FROM users")
scope.SetUser(sentry.User{ID: "123"})
sentry.CaptureException(err)
})
// 事务追踪
transaction := sentry.StartTransaction(
context.TODO(),
"GET /api/users",
sentry.OpName("http.server"),
)
defer transaction.Finish()
span := transaction.StartChild("db.query")
// 数据库操作...
span.Finish()
Java 集成 #
Maven 配置 #
xml
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry</artifactId>
<version>7.0.0</version>
</dependency>
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-spring-boot-starter</artifactId>
<version>7.0.0</version>
</dependency>
Gradle 配置 #
groovy
implementation 'io.sentry:sentry:7.0.0'
implementation 'io.sentry:sentry-spring-boot-starter:7.0.0'
Spring Boot 配置 #
properties
# application.properties
sentry.dsn=https://xxxxxxxx@o123456.ingest.sentry.io/1234567
sentry.environment=production
sentry.release=my-spring-app@1.0.0
sentry.traces-sample-rate=0.1
sentry.send-default-pii=true
java
// SentryConfig.java
import io.sentry.Sentry;
import io.sentry.spring.SentryExceptionResolver;
import io.sentry.spring.SentryServletContextInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SentryConfig {
@Bean
public SentryExceptionResolver sentryExceptionResolver() {
return new SentryExceptionResolver();
}
@Bean
public SentryServletContextInitializer sentryServletContextInitializer() {
return new SentryServletContextInitializer();
}
}
手动捕获错误 #
java
import io.sentry.Sentry;
import io.sentry.SentryLevel;
// 捕获异常
try {
int result = 10 / 0;
} catch (Exception e) {
Sentry.captureException(e);
}
// 捕获消息
Sentry.captureMessage("Something went wrong", SentryLevel.WARNING);
// 使用 Scope
Sentry.withScope(scope -> {
scope.setTag("category", "database");
scope.setExtra("query", "SELECT * FROM users");
scope.setUser(new User().setId("123").setEmail("user@example.com"));
Sentry.captureException(exception);
});
// 事务追踪
ITransaction transaction = Sentry.startTransaction("processOrder", "task");
try {
ISpan span = transaction.startChild("db.query", "fetch user");
User user = userRepository.findById(userId);
span.finish();
span = transaction.startChild("api.call", "payment service");
paymentService.charge(user);
span.finish();
} finally {
transaction.finish();
}
Spring MVC Controller #
java
import io.sentry.Sentry;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
Sentry.setTag("user.id", String.valueOf(id));
try {
return userService.findById(id);
} catch (UserNotFoundException e) {
Sentry.captureException(e);
throw new ResponseStatusException(HttpStatus.NOT_FOUND, "User not found");
}
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
Sentry.captureException(e);
return ResponseEntity.status(500).body("Internal Server Error");
}
}
数据库集成 #
SQLAlchemy (Python) #
python
import sentry_sdk
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from sqlalchemy import create_engine
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations=[SqlalchemyIntegration()],
traces_sample_rate=0.1,
)
engine = create_engine("postgresql://user:pass@localhost/db")
Redis (Python) #
python
import sentry_sdk
from sentry_sdk.integrations.redis import RedisIntegration
import redis
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations=[RedisIntegration()],
traces_sample_rate=0.1,
)
r = redis.Redis(host="localhost", port=6379)
MongoDB (Node.js) #
javascript
const Sentry = require("@sentry/node");
const { MongoIntegration } = require("@sentry/integrations");
Sentry.init({
dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations: [new MongoIntegration()],
tracesSampleRate: 0.1,
});
任务队列集成 #
Celery (Python) #
python
import sentry_sdk
from sentry_sdk.integrations.celery import CeleryIntegration
from celery import Celery
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations=[CeleryIntegration()],
traces_sample_rate=0.1,
)
app = Celery("tasks", broker="redis://localhost:6379")
@app.task
def process_order(order_id):
with sentry_sdk.start_transaction(
op="task",
name="process_order",
) as transaction:
sentry_sdk.set_tag("order_id", order_id)
# 处理订单...
RQ (Python) #
python
import sentry_sdk
from sentry_sdk.integrations.rq import RqIntegration
from rq import Queue
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations=[RqIntegration()],
)
def process_task(arg):
# 任务逻辑...
pass
q = Queue()
q.enqueue(process_task, "argument")
日志集成 #
Python logging #
python
import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration
import logging
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
integrations=[
LoggingIntegration(
level=logging.INFO,
event_level=logging.ERROR,
),
],
)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.error("This will be sent to Sentry")
Winston (Node.js) #
javascript
const Sentry = require("@sentry/node");
const winston = require("winston");
const { SentryTransport } = require("@sentry/winston");
Sentry.init({
dsn: "https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
});
const logger = winston.createLogger({
transports: [
new winston.transports.Console(),
new SentryTransport({
level: "error",
}),
],
});
logger.error("This will be sent to Sentry");
后端最佳实践 #
1. 请求上下文 #
python
# Flask
from flask import request
import sentry_sdk
@app.before_request
def before_request():
sentry_sdk.set_user({
"id": request.headers.get("X-User-ID"),
"ip_address": request.remote_addr,
})
sentry_sdk.set_tag("endpoint", request.endpoint)
2. 数据库查询追踪 #
python
import sentry_sdk
def query_users():
with sentry_sdk.start_span(
op="db.query",
description="SELECT * FROM users",
) as span:
span.set_data("db.system", "postgresql")
span.set_data("db.statement", "SELECT * FROM users")
users = db.execute("SELECT * FROM users")
return users
3. 外部 API 调用追踪 #
python
import sentry_sdk
import requests
def fetch_external_data(url):
with sentry_sdk.start_span(
op="http.client",
description=f"GET {url}",
) as span:
span.set_data("url", url)
span.set_data("method", "GET")
response = requests.get(url)
span.set_data("status_code", response.status_code)
return response.json()
4. 错误过滤 #
python
import sentry_sdk
def before_send(event, hint):
# 过滤健康检查
if event.get("request", {}).get("url", "").endswith("/health"):
return None
# 过滤特定错误
if "exc_info" in hint:
exc_type, exc_value, tb = hint["exc_info"]
if isinstance(exc_value, (ConnectionError, TimeoutError)):
return None
return event
sentry_sdk.init(
dsn="https://xxxxxxxx@o123456.ingest.sentry.io/1234567",
before_send=before_send,
)
5. 敏感数据过滤 #
python
import sentry_sdk
def before_send(event, hint):
# 过滤请求体中的敏感字段
request = event.get("request", {})
body = request.get("data", {})
if isinstance(body, dict):
sensitive_fields = ["password", "token", "credit_card"]
for field in sensitive_fields:
if field in body:
body[field] = "[Filtered]"
return event
下一步 #
现在你已经掌握了后端集成的知识,接下来学习 性能监控 了解如何监控应用性能!
最后更新:2026-03-29