关于 sentry-dotnet-sdk
sentry-dotnet-sdk 是一项扫描 .NET 项目并指导配置 Sentry 可观测功能的技能。它根据框架选择软件包和初始化方式,并逐步说明配置与验证。
主要功能
- 01扫描项目框架与依赖
- 02按框架匹配 Sentry 软件包
- 03指导错误监控与追踪
- 04配置日志、性能分析、指标与定时任务
- 05说明符号上传与验证
适用场景
- 01为 ASP.NET Core 应用添加 Sentry
- 02在 WPF 或 MAUI 中设置异常捕获
- 03为 .NET 服务配置追踪
- 04为定时任务启用监控
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ getsentry/ sentry-for-ai --skill sentry-dotnet-sdk安装后在 Claude Code 中输入/sentry-dotnet-sdk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/crons.mderror-monitoring.mdlogging.mdmetrics.mdprofiling.mdtracing.md详细介绍
Sentry .NET SDK
一款主张鲜明的向导,可扫描你的 .NET 项目,并指导你完成 Sentry 设置:在所有主流 .NET 框架中配置错误监控、分布式追踪、性能分析、结构化日志记录和 Cron 监控。
在以下情况下调用此技能
- 用户要求“将 Sentry 添加到 .NET”“在 C# 中设置 Sentry”或“为 ASP.NET Core 安装 Sentry”
- 用户希望为 .NET 应用启用错误监控、追踪、性能分析、日志记录或 Cron 监控
- 用户提到
SentrySdk.Init、UseSentry、Sentry.AspNetCore或Sentry.Maui - 用户希望捕获 WPF、WinForms、MAUI 或 Azure Functions 中未处理的异常
- 用户询问
SentryOptions、BeforeSend、TracesSampleRate或符号上传
注意: 以下 SDK 版本和 API 对应
SentryNuGet 包 ≥6.1.0(OTLP 导出要求 ≥6.5.0)。 实现前,务必对照 docs.sentry.io/platforms/dotnet/ 进行核实。
阶段 1:检测
提出任何建议前,运行以下命令以了解项目:
# Detect framework type — find all .csproj files
find . -name "*.csproj" | head -20
# Detect framework targets
grep -r "TargetFramework\|Project Sdk" --include="*.csproj" .
# Check for existing Sentry packages
grep -r "Sentry" --include="*.csproj" . | grep "PackageReference"
# Check startup files
ls Program.cs src/Program.cs App.xaml.cs MauiProgram.cs 2>/dev/null
# Check for appsettings
ls appsettings.json src/appsettings.json 2>/dev/null
# Check for logging libraries
grep -r "Serilog\|NLog\|log4net" --include="*.csproj" .
# Check for companion frontend
ls ../frontend ../client ../web 2>/dev/null
cat ../package.json 2>/dev/null | grep -E '"next"|"react"|"vue"' | head -3
需要确定的信息:
| 问题 | 影响 |
|---|---|
| 框架类型? | 决定应使用的包和初始化模式 |
| .NET 版本? | 推荐使用 .NET 8+;支持 .NET Framework 4.6.2+ |
| 是否已安装 Sentry? | 跳过安装,进入功能配置 |
| 日志库(Serilog、NLog)? | 推荐匹配的 Sentry sink/target |
| 异步/托管应用(ASP.NET Core)? | 在 WebHost 上使用 UseSentry();无需 IsGlobalModeEnabled |
| 桌面应用(WPF、WinForms、WinUI)? | 必须设置 IsGlobalModeEnabled = true |
| 无服务器应用(Azure Functions、Lambda)? | 必须设置 FlushOnCompletedRequest = true |
| 是否发现前端目录? | 触发阶段 4 的交叉链接 |
框架 → 包映射:
| 检测结果 | 要安装的包 |
|---|---|
Sdk="Microsoft.NET.Sdk.Web"(ASP.NET Core) | Sentry.AspNetCore |
App.xaml.cs 中有 Application 基类 | Sentry(WPF) |
Program.cs 中有 [STAThread] | Sentry(WinForms) |
MauiProgram.cs | Sentry.Maui |
WebAssemblyHostBuilder | Sentry.AspNetCore.Blazor.WebAssembly |
FunctionsStartup | Sentry.Extensions.Logging + Sentry.OpenTelemetry |
HttpApplication / Global.asax | Sentry.AspNet |
| 通用主机 / Worker Service | Sentry.Extensions.Logging |
阶段 2:推荐
根据发现的情况,给出具体建议。先提出方案,不要问开放式问题。
推荐配置(核心覆盖):
- ✅ 错误监控 — 始终启用;捕获未处理的异常、结构化捕获内容和作用域补充信息
- ✅ 追踪 — ASP.NET Core 和托管应用始终启用;自动检测 HTTP 请求和 EF Core 查询
- ✅ 日志记录 — 推荐所有应用启用;将 ILogger / Serilog / NLog 条目作为面包屑和事件发送到 Sentry
可选配置(增强可观测性):
- ⚡ 性能分析 — CPU 性能分析;推荐用于运行在 .NET 6+ 上、性能关键的服务
- ⚡ 指标 — 与追踪关联的计数器、仪表和分布;推荐用于需要自定义业务指标的应用
- ⚡ Cron 监控 — 检测遗漏或失败的计划任务;检测到 Hangfire、Quartz.NET 或计划端点时建议启用
推荐逻辑:
| 功能 | 推荐条件 |
|---|---|
| 错误监控 | 始终 — 不可或缺的基础配置 |
| 追踪 | ASP.NET Core 始终启用 — 请求追踪、EF Core span 和 HttpClient span 价值很高 |
| 日志记录 | 应用使用 ILogger<T>、Serilog、NLog 或 log4net |
| 性能分析 | .NET 6+ 上的性能关键型服务 |
| 指标 | 应用需要自定义业务指标(请求计数、队列深度、响应时间) |
| Cron 监控 | 应用使用 Hangfire、Quartz.NET 或计划 Azure Functions |
建议这样说:“我建议设置错误监控 + 追踪 + 日志记录。要我也添加性能分析或 Cron 监控吗?”
阶段 3:引导
选项 1:向导(推荐)
你需要自行运行此向导 — 向导会打开浏览器供你登录,并要求进行 Agent 无法处理的交互式输入。请复制并粘贴到终端中:
npx @sentry/wizard@latest -i dotnet此向导会处理登录、组织/项目选择、DSN 配置,以及 MSBuild 符号上传设置,以便在生产环境中查看可读的堆栈跟踪。
完成后,请返回并跳转到验证。
如果用户跳过向导,请继续执行下方的选项 2(手动设置)。
选项 2:手动设置
安装合适的包
# ASP.NET Core
dotnet add package Sentry.AspNetCore -v 6.1.0
# WPF or WinForms or Console
dotnet add package Sentry -v 6.1.0
# .NET MAUI
dotnet add package Sentry.Maui -v 6.1.0
# Blazor WebAssembly
dotnet add package Sentry.AspNetCore.Blazor.WebAssembly -v 6.1.0
# Azure Functions (Isolated Worker)
dotnet add package Sentry.Extensions.Logging -v 6.1.0
dotnet add package Sentry.OpenTelemetry -v 6.1.0
# Classic ASP.NET (System.Web / .NET Framework)
dotnet add package Sentry.AspNet -v 6.1.0
ASP.NET Core — Program.cs
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseSentry(options =>
{
options.Dsn = Environment.GetEnvironmentVariable("SENTRY_DSN")
?? "___YOUR_DSN___";
options.Debug = true; // disable in production
options.SendDefaultPii = true; // captures user IP, name, email
options.MaxRequestBodySize = RequestSize.Always;
options.MinimumBreadcrumbLevel = LogLevel.Debug;
options.MinimumEventLevel = LogLevel.Warning;
options.TracesSampleRate = 1.0; // tune to 0.1–0.2 in production
options.SetBeforeSend((@event, hint) =>
{
@event.ServerName = null; // scrub hostname from events
return @event;
});
});
var app = builder.Build();
app.Run();
appsettings.json(备用配置):
{
"Sentry": {
"Dsn": "___YOUR_DSN___",
"SendDefaultPii": true,
"MaxRequestBodySize": "Always",
"MinimumBreadcrumbLevel": "Debug",
"MinimumEventLevel": "Warning",
"AttachStacktrace": true,
"Debug": true,
"TracesSampleRate": 1.0,
"Environment": "production",
"Release": "[email protected]"
}
}
环境变量(使用双下划线作为分隔符):
export Sentry__Dsn="https://[email protected]/0"
export Sentry__TracesSampleRate="0.1"
export Sentry__Environment="staging"
WPF — App.xaml.cs
⚠️ 关键:请在构造函数中初始化,而不是在
OnStartup()中初始化。构造函数触发得更早,能够捕获更多故障模式。
using System.Windows;
using Sentry;
public partial class App : Application
{
public App()
{
SentrySdk.Init(options =>
{
options.Dsn = "___YOUR_DSN___";
options.Debug = true;
options.SendDefaultPii = true;
options.TracesSampleRate = 1.0;
options.IsGlobalModeEnabled = true; // required for all desktop apps
});
// Capture WPF UI-thread exceptions before WPF's crash dialog appears
DispatcherUnhandledException += App_DispatcherUnhandledException;
}
private void App_DispatcherUnhandledException(
object sender,
System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
SentrySdk.CaptureException(e.Exception);
// Set e.Handled = true to prevent crash dialog and keep app running
}
}
WinForms — Program.cs
using System;
using System.Windows.Forms;
using Sentry;
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
// Required: allows Sentry to see unhandled WinForms exceptions
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
using (SentrySdk.Init(new SentryOptions
{
Dsn = "___YOUR_DSN___",
Debug = true,
TracesSampleRate = 1.0,
IsGlobalModeEnabled = true, // required for desktop apps
}))
{
Application.Run(new MainForm());
} // Disposing flushes all pending events
}
}
.NET MAUI — MauiProgram.cs
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseSentry(options =>
{
options.Dsn = "___YOUR_DSN___";
options.Debug = true;
options.SendDefaultPii = true;
options.TracesSampleRate = 1.0;
// MAUI-specific: opt-in breadcrumbs (off by default — PII risk)
options.IncludeTextInBreadcrumbs = false;
options.IncludeTitleInBreadcrumbs = false;
options.IncludeBackgroundingStateInBreadcrumbs = false;
});
return builder.Build();
}
}
Blazor WebAssembly — Program.cs
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.UseSentry(options =>
{
options.Dsn = "___YOUR_DSN___";
options.Debug = true;
options.SendDefaultPii = true;
options.TracesSampleRate = 0.1;
});
// Hook logging pipeline without re-initializing the SDK
builder.Logging.AddSentry(o => o.InitializeSdk = false);
await builder.Build().RunAsync();
Azure Functions(独立工作进程)— Program.cs
**推荐:**安装
Sentry.OpenTelemetry.Exporter(≥6.5.0)以进行 OTLP 导出。也可以使用Sentry.OpenTelemetry实现桥接模式。
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Trace;
// Package: Sentry.OpenTelemetry.Exporter
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureLogging(logging =>
{
logging.AddSentry(options =>
{
options.Dsn = "___YOUR_DSN___";
options.Debug = true;
options.TracesSampleRate = 1.0;
options.UseOtlp(); // send OTel spans via OTLP (requires 6.5.0+)
});
})
.ConfigureServices(services =>
{
services.AddOpenTelemetry().WithTracing(builder =>
{
builder
.AddHttpClientInstrumentation()
.AddSentryOtlpExporter("___YOUR_DSN___"); // route spans to Sentry OTLP endpoint
});
})
.Build();
await host.RunAsync();
AWS Lambda — LambdaEntryPoint.cs
public class LambdaEntryPoint : APIGatewayProxyFunction
{
protected override void Init(IWebHostBuilder builder)
{
builder
.UseSentry(options =>
{
options.Dsn = "___YOUR_DSN___";
options.TracesSampleRate = 1.0;
options.FlushOnCompletedRequest = true; // REQUIRED for Lambda
})
.UseStartup<Startup>();
}
}
经典 ASP.NET — Global.asax.cs
public class MvcApplication : HttpApplication
{
private IDisposable _sentry;
protected void Application_Start()
{
_sentry = SentrySdk.Init(options =>
{
options.Dsn = "___YOUR_DSN___";
options.TracesSampleRate = 1.0;
options.AddEntityFramework(); // EF6 query breadcrumbs
options.AddAspNet(); // Classic ASP.NET integration
});
}
protected void Application_Error() => Server.CaptureLastError();
protected void Application_BeginRequest() => Context.StartSentryTransaction();
protected void Application_EndRequest() => Context.FinishSentryTransaction();
protected void Application_End() => _sentry?.Dispose();
}
符号上传(可读的堆栈跟踪)
如果没有调试符号,堆栈跟踪只会显示方法名,不会显示文件名或行号。SDK 会通过 Release 构建中的 MSBuild 属性上传 PDB 文件(以及可选的源代码):
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<SentryOrg>___ORG_SLUG___</SentryOrg>
<SentryProject>___PROJECT_SLUG___</SentryProject>
<SentryUploadSymbols>true</SentryUploadSymbols>
<SentryUploadSources>true</SentryUploadSources>
<SentryCreateRelease>true</SentryCreateRelease>
<SentrySetCommits>true</SentrySetCommits>
</PropertyGroup>
上传需要在 CI 中设置 SENTRY_AUTH_TOKEN(一个密钥)。关于如何创建令牌和配置 CI,请参阅 sentry-source-maps。SentryCreateRelease / SentrySetCommits 属性还会创建包含疑似相关提交的版本,请参阅 sentry-releases。
对于每项商定的功能
加载对应的参考文件并按其步骤操作:
| 功能 | 参考文件 | 在以下情况下加载…… |
|---|---|---|
| 错误监控 | references/error-monitoring.md | 始终加载 — CaptureException、作用域、信息补充、过滤 |
| 跟踪 | references/tracing.md | 服务端应用、分布式跟踪、EF Core 跨度、自定义检测 |
| 性能分析 | references/profiling.md | .NET 6+ 上的性能关键型应用 |
| 日志记录 | references/logging.md | ILogger<T>、Serilog、NLog、log4net 集成 |
| 指标 | references/metrics.md | 自定义计数器、仪表、分布;EmitCounter、EmitGauge、EmitDistribution |
| 定时任务 | references/crons.md | Hangfire、Quartz.NET 或定时函数监控 |
对于每项功能:阅读参考文件,严格按照其中的步骤操作,并在继续之前进行验证。
配置参考
核心 SentryOptions
| 选项 | 类型 | 默认值 | 环境变量 | 说明 |
|---|---|---|---|---|
Dsn | string | — | SENTRY_DSN | 必填。未设置时 SDK 将禁用。 |
Debug | bool | false | — | SDK 诊断输出。生产环境中请禁用。 |
DiagnosticLevel | SentryLevel | Debug | — | Debug、Info、Warning、Error、Fatal |
Release | string | 自动 | SENTRY_RELEASE | 根据程序集版本和 git SHA 自动检测 |
Environment | string | "production" | SENTRY_ENVIRONMENT | 调试器已附加时为 "debug" |
Dist | string | — | — | 构建变体。最多 64 个字符。 |
SampleRate | float | 1.0 | — | 错误事件采样率,范围为 0.0–1.0 |
TracesSampleRate | double | 0.0 | — | 事务采样。必须大于 0 才能启用。 |
TracesSampler | Func<SamplingContext, double> | — | — | 按事务动态采样;优先于 TracesSampleRate |
ProfilesSampleRate | double | 0.0 | — | 要进行性能分析的已追踪事务占比。需要 Sentry.Profiling。 |
SendDefaultPii | bool | false | — | 包含用户 IP、姓名和电子邮件 |
AttachStacktrace | bool | true | — | 为所有消息附加堆栈跟踪 |
MaxBreadcrumbs | int | 100 | — | 每个事件存储的面包屑上限 |
IsGlobalModeEnabled | bool | false* | — | *MAUI、Blazor WASM 中自动设为 true。WPF、WinForms、Console 中必须设为 true。 |
AutoSessionTracking | bool | false* | — | *MAUI 中自动设为 true。启用后可使用 Release Health。 |
CaptureFailedRequests | bool | true | — | 自动捕获 HTTP 客户端错误 |
CacheDirectoryPath | string | — | — | 离线事件缓存目录 |
ShutdownTimeout | TimeSpan | — | — | 关闭时等待事件刷新完成的最长时间 |
HttpProxy | string | — | — | Sentry 请求的代理 URL |
EnableBackpressureHandling | bool | true | — | 发送失败时自动降低采样率 |
TraceIgnoreStatusCodes | IList<HttpStatusCodeRange> | [] | — | 丢弃 HTTP 响应状态码匹配任意范围的事务;例如 [404] 或 [(500, 599)] |
StrictTraceContinuation | bool | false | — | 设为 true 时,如果只有一端(SDK 或传入的 sentry-org_id baggage)具有 org ID,则会启动新的追踪。若两端均存在但 org ID 不同,则无论此设置如何,都会启动新的追踪。(需要 ≥6.6.0) |
OrgId | string | 自动 | — | 用于追踪验证的组织 ID;根据 DSN 子域自动解析(例如,o123.ingest.sentry.io → "123")。建议在可自托管的 Sentry、本地 Relay 或自定义域名场景中显式设置(需要 ≥6.6.0) |
ASP.NET Core 扩展选项(SentryAspNetCoreOptions)
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
MaxRequestBodySize | RequestSize | None | None、Small(约 4 KB)、Medium(约 10 KB)、Always |
MinimumBreadcrumbLevel | LogLevel | Information | 面包屑的最低日志级别 |
MinimumEventLevel | LogLevel | Error | 作为 Sentry 事件发送的最低日志级别 |
CaptureBlockingCalls | bool | false | 检测 .Wait() / .Result 导致的线程池耗尽 |
FlushOnCompletedRequest | bool | false | Lambda / 无服务器场景必需 |
IncludeActivityData | bool | false | 捕获 System.Diagnostics.Activity 值 |
MAUI 扩展选项(SentryMauiOptions)
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
IncludeTextInBreadcrumbs | bool | false | Button、Label、Entry 元素中的文本。⚠️ 存在 PII 风险。 |
IncludeTitleInBreadcrumbs | bool | false | Window、Page 元素中的标题。⚠️ 存在 PII 风险。 |
IncludeBackgroundingStateInBreadcrumbs | bool | false | Window.Backgrounding 事件状态。⚠️ 存在 PII 风险。 |
环境变量
| 变量 | 用途 |
|---|---|
SENTRY_DSN | 项目 DSN |
SENTRY_RELEASE | 应用版本(例如 [email protected]) |
SENTRY_ENVIRONMENT | 部署环境名称 |
SENTRY_AUTH_TOKEN | MSBuild / sentry-cli 符号上传身份验证令牌 |
**ASP.NET Core:**使用双下划线 __ 作为层级分隔符:
export Sentry__Dsn="https://..."
export Sentry__TracesSampleRate="0.1"
MSBuild 符号上传属性
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
SentryOrg | string | — | Sentry 组织 slug |
SentryProject | string | — | Sentry 项目 slug |
SentryUploadSymbols | bool | false | 上传 PDB 文件,以在堆栈跟踪中显示行号 |
SentryUploadSources | bool | false | 上传源文件,以提供源代码上下文 |
SentryCreateRelease | bool | false | 构建时自动创建 Sentry 发布版本 |
SentrySetCommits | bool | false | 将 git 提交与发布版本关联 |
SentryUrl | string | — | 自托管 Sentry URL |
验证
完成向导设置或手动设置后,添加一条测试抛出语句,并在验证后将其删除:
// ASP.NET Core: add a temporary endpoint
app.MapGet("/sentry-test", () =>
{
throw new Exception("Sentry test error — delete me");
});
// Or capture explicitly anywhere
SentrySdk.CaptureException(new Exception("Sentry test error — delete me"));
然后检查 Sentry Issues 控制面板——错误应在约 30 秒内出现。
验证清单:
| 检查项 | 方法 |
|---|---|
| 已捕获异常 | 抛出测试异常,并在 Sentry Issues 中确认 |
| 堆栈跟踪可读 | 检查是否显示文件名和行号 |
| 跟踪已启用 | 在 Performance 选项卡中检查事务 |
| 日志已接入 | 通过 ILogger 记录错误,检查其是否显示为 Sentry 面包屑 |
| 符号上传正常 | 堆栈跟踪显示 Controllers/HomeController.cs:42,而非 <unknown> |
第 4 阶段:交叉关联
完成 .NET 设置后,检查是否存在配套的前端项目:
# Check for frontend in adjacent directories
ls ../frontend ../client ../web ../app 2>/dev/null
# Check for JavaScript framework indicators
cat ../package.json 2>/dev/null | grep -E '"next"|"react"|"vue"|"nuxt"' | head -3
如果发现前端项目,建议使用相应的 SDK 技能:
| 检测到的前端 | 建议的技能 |
|---|---|
Next.js(package.json 中包含 "next") | sentry-nextjs-sdk |
React SPA(包含 "react",且不包含 "next") | @sentry/react——参见 docs.sentry.io/platforms/javascript/guides/react/ |
| Vue.js | @sentry/vue——参见 docs.sentry.io/platforms/javascript/guides/vue/ |
| Nuxt | @sentry/nuxt——参见 docs.sentry.io/platforms/javascript/guides/nuxt/ |
将前端和后端连接到同一个 Sentry 项目,即可启用分布式跟踪——在单个跟踪视图中查看浏览器、.NET 服务及任何下游 API。
故障排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 未显示事件 | DSN 配置错误 | 设置 Debug = true,并检查控制台输出中的 SDK 诊断消息 |
| 堆栈跟踪未显示文件/行号 | 未上传 PDB 文件 | 将 SentryUploadSymbols=true 添加到 .csproj;在 CI 中设置 SENTRY_AUTH_TOKEN |
| 缺少 WPF/WinForms 异常 | 未设置 IsGlobalModeEnabled | 在 SentrySdk.Init() 中设置 options.IsGlobalModeEnabled = true |
| Lambda/无服务器事件丢失 | 容器在刷新前冻结 | 设置 options.FlushOnCompletedRequest = true |
| 缺少 WPF UI 线程异常 | 未连接 DispatcherUnhandledException | 在构造函数中(而不是 OnStartup 中)注册 App.DispatcherUnhandledException |
| Azure Functions 中出现重复的 HTTP span | Sentry 和 OTel 都对 HTTP 进行检测 | 设置 options.DisableSentryHttpMessageHandler = true |
TracesSampleRate 没有效果 | 速率为 0.0(默认值) | 设置 TracesSampleRate > 0 以启用追踪 |
忽略 appsettings.json 中的值 | 配置键格式错误 | 使用扁平键 "Sentry:Dsn" 或环境变量 Sentry__Dsn(双下划线) |
BeforeSend 丢弃所有事件 | 钩子无条件返回 null | 检查筛选逻辑;仅对要丢弃的事件返回 null |
| 未捕获 MAUI 原生崩溃 | 包错误 | 确认已安装 Sentry.Maui(而不只是 Sentry) |