mcpField
S
sentry-dotnet-sdk

sentry-dotnet-sdk

github.com/getsentry开发25293 次安装35 周前更新
代码仓库

关于 sentry-dotnet-sdk

面向 .NET 开发者的 Sentry 配置向导技能,会扫描项目并按框架指导错误监控、追踪、分析、日志和定时任务监控配置。

主要功能

  1. 01扫描项目并识别 .NET 框架
  2. 02按框架推荐 Sentry 包与配置
  3. 03配置错误监控和分布式追踪
  4. 04配置分析、日志及定时任务监控
  5. 05指导符号上传与验证

适用场景

  1. 01为 ASP.NET Core 或桌面 .NET 应用接入 Sentry
  2. 02为 Azure Functions 或 Lambda 配置监控
  3. 03为 .NET 服务配置追踪和日志
  4. 04排查堆栈信息或事件捕获问题

安装

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

$npx skills add https://github.com/getsentry/sentry-agent-skills --skill sentry-dotnet-sdk

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
crons.md
error-monitoring.md
logging.md
profiling.md
tracing.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 以 Sentry NuGet 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.csSentry(WPF)
Program.cs 中包含 [STAThread]Sentry(WinForms)
MauiProgram.csSentry.Maui
WebAssemblyHostBuilderSentry.AspNetCore.Blazor.WebAssembly
FunctionsStartupSentry.Extensions.Logging + Sentry.OpenTelemetry
HttpApplication / Global.asaxSentry.AspNet
通用主机 / Worker ServiceSentry.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.mdILogger<T>、Serilog、NLog、log4net 集成
Cronsreferences/crons.mdHangfire、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
选项类型默认值环境变量说明
Dsnstring—SENTRY_DSN必填。未设置时,SDK 将被禁用。
Debugboolfalse—SDK 诊断输出。生产环境中请禁用。
DiagnosticLevelSentryLevelDebug—Debug、Info、Warning、Error、Fatal
Releasestring自动SENTRY_RELEASE根据程序集版本和 git SHA 自动检测
Environmentstring"production"SENTRY_ENVIRONMENT调试器已附加时为 "debug"
Diststring——构建变体。最多 64 个字符。
SampleRatefloat1.0—错误事件采样率,范围为 0.0–1.0
TracesSampleRatedouble0.0—事务采样。必须大于 0 才能启用。
TracesSamplerFunc<SamplingContext, double>——按事务动态采样;优先于 TracesSampleRate
ProfilesSampleRatedouble0.0—被跟踪事务的性能分析采样比例。需要 Sentry.Profiling。
SendDefaultPiiboolfalse—包含用户 IP、姓名和电子邮件
AttachStacktracebooltrue—为所有消息附加堆栈跟踪
MaxBreadcrumbsint100—每个事件存储的面包屑上限
IsGlobalModeEnabledboolfalse*—*MAUI、Blazor WASM 中自动设为 true。WPF、WinForms、Console 中必须设为 true。
AutoSessionTrackingboolfalse*—*MAUI 中自动设为 true。启用后可使用 Release Health。
CaptureFailedRequestsbooltrue—自动捕获 HTTP 客户端错误
CacheDirectoryPathstring——离线事件缓存目录
ShutdownTimeoutTimeSpan——关闭时等待事件刷新完成的最长时间
HttpProxystring——Sentry 请求的代理 URL
EnableBackpressureHandlingbooltrue—传输失败时自动降低采样率
ASP.NET Core 扩展选项(SentryAspNetCoreOptions)
选项类型默认值说明
MaxRequestBodySizeRequestSizeNoneNone、Small(约 4 KB)、Medium(约 10 KB)、Always
MinimumBreadcrumbLevelLogLevelInformation面包屑的最低日志级别
MinimumEventLevelLogLevelError作为 Sentry 事件发送的最低日志级别
CaptureBlockingCallsboolfalse检测 .Wait() / .Result 导致的线程池耗尽
FlushOnCompletedRequestboolfalseLambda / 无服务器环境必需
IncludeActivityDataboolfalse捕获 System.Diagnostics.Activity 值
MAUI 扩展选项(SentryMauiOptions)
选项类型默认值说明
IncludeTextInBreadcrumbsboolfalse来自 Button、Label、Entry 元素的文本。⚠️ 存在 PII 风险。
IncludeTitleInBreadcrumbsboolfalse来自 Window、Page 元素的标题。⚠️ 存在 PII 风险。
IncludeBackgroundingStateInBreadcrumbsboolfalseWindow.Backgrounding 事件状态。⚠️ 存在 PII 风险。
环境变量
变量用途
SENTRY_DSN项目 DSN
SENTRY_RELEASE应用版本(例如 [email protected])
SENTRY_ENVIRONMENT部署环境名称
SENTRY_AUTH_TOKENMSBuild / sentry-cli 符号上传身份验证令牌

ASP.NET Core: 使用双下划线 __ 作为层级分隔符:

export Sentry__Dsn="https://..."
export Sentry__TracesSampleRate="0.1"
MSBuild 符号上传属性
属性类型默认值描述
SentryOrgstring—Sentry 组织 slug
SentryProjectstring—Sentry 项目 slug
SentryUploadSymbolsboolfalse上传 PDB 文件,以便在堆栈跟踪中显示行号
SentryUploadSourcesboolfalse上传源文件,以提供源代码上下文
SentryCreateReleaseboolfalse在构建期间自动创建 Sentry 发布版本
SentrySetCommitsboolfalse将 git 提交关联到发布版本
SentryUrlstring—可自托管的 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 spanSentry 和 OTel 都对 HTTP 进行检测设置 options.DisableSentryHttpMessageHandler = true
TracesSampleRate 无效采样率为 0.0(默认值)设置 TracesSampleRate > 0 以启用追踪
忽略 appsettings.json 中的值配置键格式错误使用扁平键 "Sentry:Dsn" 或环境变量 Sentry__Dsn(双下划线)
BeforeSend 丢弃所有事件钩子无条件返回 null检查筛选逻辑;仅对要丢弃的事件返回 null
未捕获 MAUI 原生崩溃包错误确认已安装 Sentry.Maui(而不只是 Sentry)

评论

支持 Markdown