关于 sentry-dotnet-sdk
面向 .NET 开发者的 Sentry 配置向导技能,会扫描项目并按框架指导错误监控、追踪、分析、日志和定时任务监控配置。
主要功能
- 01扫描项目并识别 .NET 框架
- 02按框架推荐 Sentry 包与配置
- 03配置错误监控和分布式追踪
- 04配置分析、日志及定时任务监控
- 05指导符号上传与验证
适用场景
- 01为 ASP.NET Core 或桌面 .NET 应用接入 Sentry
- 02为 Azure Functions 或 Lambda 配置监控
- 03为 .NET 服务配置追踪和日志
- 04排查堆栈信息或事件捕获问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ getsentry/ sentry-agent-skills --skill sentry-dotnet-sdk安装后在 Claude Code 中输入/sentry-dotnet-sdk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/crons.mderror-monitoring.mdlogging.mdprofiling.mdtracing.md详细介绍
Sentry .NET SDK
一个主观性较强的向导,可扫描你的 .NET 项目,并引导你完成完整的 Sentry 设置:错误监控、分布式追踪、性能分析、结构化日志记录,以及覆盖所有主流 .NET 框架的定时任务监控。
在以下情况下调用此技能
- 用户要求“将 Sentry 添加到 .NET”“在 C# 中设置 Sentry”或“为 ASP.NET Core 安装 Sentry”
- 用户希望为 .NET 应用添加错误监控、追踪、性能分析、日志记录或定时任务监控
- 用户提到
SentrySdk.Init、UseSentry、Sentry.AspNetCore或Sentry.Maui - 用户希望捕获 WPF、WinForms、MAUI 或 Azure Functions 中未处理的异常
- 用户询问
SentryOptions、BeforeSend、TracesSampleRate或符号上传
注意: 以下 SDK 版本和 API 以
SentryNuGet packages ≥6.1.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 |
带有 Application 基类的 App.xaml.cs | 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+ 上的性能关键型服务
- ⚡ 定时任务 — 检测错过或失败的计划任务;检测到 Hangfire、Quartz.NET 或计划端点时推荐启用
推荐逻辑:
| 功能 | 推荐条件... |
|---|---|
| 错误监控 | 始终 — 不容妥协的基础配置 |
| 追踪 | ASP.NET Core 始终启用 — 请求追踪、EF Core spans、HttpClient spans 价值很高 |
| 日志记录 | 应用使用 ILogger<T>、Serilog、NLog 或 log4net |
| 性能分析 | .NET 6+ 上的性能关键型服务 |
| 定时任务 | 应用使用 Hangfire、Quartz.NET 或计划 Azure Functions |
建议:“我建议设置错误监控 + 追踪 + 日志记录。你是否还希望我添加性能分析或定时任务监控?”
阶段 3:引导
选项 1:向导(推荐)
npx @sentry/wizard@latest -i dotnet
向导会让你登录 Sentry、选择组织和项目、配置 DSN,并设置 MSBuild 符号上传,以便在生产环境中查看可读的堆栈跟踪。
运行向导后,跳转到验证。
选项 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
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using OpenTelemetry.Trace;
using Sentry.OpenTelemetry;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services =>
{
services.AddOpenTelemetry().WithTracing(builder =>
{
builder
.AddSentry() // route OTel spans to Sentry
.AddHttpClientInstrumentation(); // capture outgoing HTTP
});
})
.ConfigureLogging(logging =>
{
logging.AddSentry(options =>
{
options.Dsn = "___YOUR_DSN___";
options.Debug = true;
options.TracesSampleRate = 1.0;
options.UseOpenTelemetry(); // let OTel drive tracing
options.DisableSentryHttpMessageHandler = true; // prevent duplicate HTTP spans
});
})
.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();
}
符号上传(可读堆栈跟踪)
没有调试符号时,堆栈跟踪只显示方法名称,不包含文件名或行号。上传 PDB 文件以获取完整的源代码上下文。
步骤 1:创建 Sentry 身份验证令牌
前往 sentry.io/settings/auth-tokens/,创建具有 project:releases 和 org:read 权限范围的令牌。
步骤 2:将 MSBuild 属性添加到 .csproj 或 Directory.Build.props:
<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>
步骤 3:在 CI 中设置 SENTRY_AUTH_TOKEN:
# GitHub Actions
- name: Build & upload symbols
run: dotnet build -c Release
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
针对每项商定的功能
加载相应的参考文件并按照其中的步骤操作:
| 功能 | 参考文件 | 加载时机…… |
|---|---|---|
| 错误监控 | references/error-monitoring.md | 始终加载 — CaptureException、作用域、上下文增强、过滤 |
| 链路追踪 | references/tracing.md | 服务端应用、分布式追踪、EF Core spans、自定义插桩 |
| 性能分析 | references/profiling.md | .NET 6+ 上的性能关键型应用 |
| 日志记录 | references/logging.md | ILogger<T>、Serilog、NLog、log4net 集成 |
| Crons | references/crons.md | Hangfire、Quartz.NET 或定时函数监控 |
对于每项功能:阅读参考文件,严格按照其中的步骤操作,并在继续之前进行验证。
验证
通过向导或手动完成设置后,添加一个测试异常,并在验证后将其移除:
// 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> |
配置参考
核心 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 | — | 传输失败时自动降低采样率 |
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 |
阶段 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 文件 | 在 .csproj 中添加 SentryUploadSymbols=true;在 CI 中设置 SENTRY_AUTH_TOKEN |
| 缺少 WPF/WinForms 异常 | 未设置 IsGlobalModeEnabled | 在 SentrySdk.Init() 中设置 options.IsGlobalModeEnabled = true |
| Lambda/无服务器事件丢失 | 容器在刷新前被冻结 | 设置 options.FlushOnCompletedRequest = true |
| 缺少 WPF UI 线程异常 | 未接入 DispatcherUnhandledException | 在构造函数中注册 App.DispatcherUnhandledException(不要在 OnStartup 中注册) |
| 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) |