简介
针对.NET Core的两种集成方式
基于 Microsoft.Extensions.Logging 的集成方式:Sentry.Extensions.Logging
基于 asp.net core 框架的集成方式:Sentry.AspNetCore
源码:https://github.com/getsentry/sentry-dotnet
官方文档:https://docs.sentry.io/platforms/dotnet/guides/aspnetcore/
使用
1.安装nuget:
Sentry.AspNetCore
2.UseSentry
hostBuilder.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseSentry((options) =>
{
options.Dsn = "xxxxxxxxxx";
});
webBuilder.UseStartup<Startup>();
});
可以通过UseSentry添加配置,也可以通过配置文件添加配置,如下:
"Sentry": {
"Dsn": "xxxxxxxxxx",
"Debug": true,
"TracesSampleRate": 1,
"MinimumEventLevel": 4,
"MinimumBreadcrumbLevel": 4
}
配置
- Dsn
DSN告诉 SDK 将事件发送到哪里。如果未提供此值,SDK 将尝试从SENTRY_DSN环境变量中读取它。如果该变量也不存在,SDK 将不会发送任何事件。 - MaxBreadcrumbs
此变量控制应捕获的面包屑的总量。这默认为100. - AttachStacktrace
启用后,堆栈跟踪会自动附加到所有记录的消息。堆栈跟踪总是附加到异常上;但是,当设置此选项时,堆栈跟踪也会随消息一起发送。
对于有堆栈跟踪和没有堆栈跟踪的事件,Sentry 中的分组是不同的。因此,当您为某些事件启用或禁用此标志时,您将获得新组。
- Environment
设置环境,默认取环境变量ASPNETCORE_ENVIRONMENT - Debug
打开或关闭调试模式。如果启用调试,如果发送事件出现问题,SDK 将尝试打印有用的调试信息。默认值为始终false。通常不建议在生产中打开它,尽管打开debug模式不会引起任何安全问题。 - BeforeSend钩子
发生的错误异常可以在发送到 sentry 服务器端之前做修改,对于要忽略的异常也可以在这个事件中做
options.BeforeSend = (sentryEvent) =>
{
// ignore TaskCanceledException/OperationCanceledException
if (sentryEvent.Exception is TaskCanceledException ||
sentryEvent.Exception is OperationCanceledException)
{
return null;
}
return sentryEvent;
};
- BeforeBreadcrumb钩子
options.BeforeBreadcrumb = breadcrumb
// 将类型是“Spammy.Logger”的面包屑丢弃
=> breadcrumb.Category == "Spammy.Logger"
? null
: breadcrumb;
- MaxBreadcrumbs
应捕获的面包屑的最大数。这默认为100. - MaxRequestBodySize
是否应捕获 HTTP 请求正文。
never:从不发送请求正文。
small:只会捕获小的请求主体。small 的截止值取决于 SDK(通常为 4KB)。
medium:会捕获中小请求(一般为10KB)。
always:只要 Sentry 可以理解,SDK 将始终捕获请求正文。
挂钩 - SampleRate
采样率,范围为0.0至1.0。默认值1.0表示发送 100% 的错误事件。如果设置为0.1仅发送 10% 的错误事件。事件是随机挑选的。 - StackTraceMode
Original(原始 )- 默认 .NET 堆栈跟踪格式。
Enhanced(增强 )- 包括async、返回类型、参数等。 - DiagnosticLevel
设置诊断日志的级别,用于 Sentry SDK 的内部日志。可选级别包括 “Debug”, “Info”, “Warning”, “Error”, “Fatal”。 - Release
- SendDefaultPii
发送默认的个人身份信息 (PII),例如用户名和 IP 地址。这有助于提供更多的上下文信息,但在某些情况下(例如遵循隐私法规),可能需要设置为 false。 - MaxCacheItems
示例
1.sentry 性能监控过滤器
public class PropertyMonitorFilter : IAsyncActionFilter
{
/// <summary>
/// sentry 性能监控
/// </summary>
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// 从依赖注入容器中获取 Sentry 的 IHub 实例
var hub = context.HttpContext.RequestServices.GetRequiredService<IHub>();
// 开始一个新的 Sentry 事务
var transaction = hub.StartTransaction("request", "http.server");
// 将事务存储在 HttpContext.Items 中,以便在请求的其他部分可以访问
context.HttpContext.Items["Transaction"] = transaction;
try
{
// 继续执行下一个中间件或操作
await next();
// 获取当前请求的路由终结点
var endpoint = context.HttpContext.GetEndpoint();
if (endpoint != null)
{
// 获取控制器操作描述符
var controllerActionDescriptor = endpoint.Metadata
.OfType<ControllerActionDescriptor>()
.FirstOrDefault();
if (controllerActionDescriptor != null)
{
// 获取控制器类型和方法信息
var controllerType = controllerActionDescriptor.ControllerTypeInfo;
var actionMethod = controllerActionDescriptor.MethodInfo;
// 判断控制器或方法是否具有 NotMonitoredAttribute 特性
var hasNotMonitoredAttribute = actionMethod.GetCustomAttribute<NotMonitoredAttribute>() != null
|| controllerType.GetCustomAttribute<NotMonitoredAttribute>() != null;
// 如果没有 NotMonitoredAttribute 特性,则结束 Sentry 事务
if (!hasNotMonitoredAttribute)
{
transaction.Finish();
}
}
}
}
catch (Exception ex)
{
// 捕获并报告异常
await HandleExceptionAsync(context.HttpContext, ex);
transaction.Finish(ex);
throw; // 重新抛出异常以确保它不会被吞掉
}
finally
{
// 确保在任何情况下事务都能结束
if (!transaction.IsFinished)
{
transaction.Finish();
}
}
}
private Task HandleExceptionAsync(HttpContext context, Exception exception)
{
// 判断异常是否为空
if (exception != null)
{
var formParameters = new Dictionary<string, object>();
if (App.User != null)
{
formParameters.Add("登录人员流水号", App.User.UserId);
formParameters.Add("登录人员姓名", App.User.UserName);
}
if (context.Request.HasFormContentType)
{
var formValues = context.Request.Form;
foreach (var key in formValues.Keys)
{
formParameters[key] = formValues[key];
}
}
SentrySdk.CaptureException(exception, o => o.SetExtras(formParameters));
}
return Task.CompletedTask;
}
}
2.读取sentry配置项
public static class SentryConfiguration
{
public static WebApplicationBuilder AddSentry(this WebApplicationBuilder builder)
{
//读取sentry配置项
SentryOptions? sentryOptions = App.GetSection<SentryOptions>("Sentry") ?? new SentryOptions();
builder.WebHost.UseSentry(o =>
{
o.Dsn = sentryOptions.Dsn;
o.Debug = sentryOptions.Debug;
o.TracesSampleRate = sentryOptions.TracesSampleRate;
o.MinimumEventLevel = sentryOptions.MinimumEventLevel;
o.MinimumBreadcrumbLevel = sentryOptions.MinimumBreadcrumbLevel;
});
return builder;
}
}
Sentry配置选项实体
public class SentryOptions
{
public string? Dsn { get; set; }
public bool Debug { get; set; }
public double TracesSampleRate { get; set; }
public LogLevel MinimumEventLevel { get; set; }
public LogLevel MinimumBreadcrumbLevel { get; set; }
}
3.Program.cs
WebApplicationBuilder? builder = WebApplication.CreateBuilder(args);
//Sentry
builder.AddSentry();
//Sentry服务
builder.Services.Configure<MvcOptions>(options => options.Filters.Add<PropertyMonitorFilter>());
参考:https://www.cnblogs.com/fanfan-90/p/16163452.html