diff --git a/src/Argon.Api/Features/Orleanse/OrleansExtension.cs b/src/Argon.Api/Features/Orleanse/OrleansExtension.cs index 016c99e..d41d267 100644 --- a/src/Argon.Api/Features/Orleanse/OrleansExtension.cs +++ b/src/Argon.Api/Features/Orleanse/OrleansExtension.cs @@ -1,6 +1,7 @@ namespace Argon.Api.Features; using ActualLab.Serialization; +using Argon.Api.Features.Sentry; using Contracts; using Env; using Extensions; @@ -17,27 +18,38 @@ public static class OrleansExtension public static WebApplicationBuilder AddOrleans(this WebApplicationBuilder builder) { builder.Services.AddSerializer(x => x.AddMessagePackSerializer(null, null, MessagePackByteSerializer.Default.Options)); - builder.Host.UseOrleans(siloBuilder => { - siloBuilder.Configure(builder.Configuration.GetSection("Orleans")).AddStreaming().UseDashboard(o => o.Port = 22832) - .AddActivityPropagation().AddAdoNetGrainStorage("PubSubStore", options => + builder.Host.UseOrleans(siloBuilder => + { + siloBuilder.Configure(builder.Configuration.GetSection("Orleans")) + .AddStreaming() + .UseDashboard(o => o.Port = 22832) + .AddActivityPropagation() + .AddIncomingGrainCallFilter() + .AddAdoNetGrainStorage("PubSubStore", options => { - options.Invariant = "Npgsql"; - options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"); + options.Invariant = "Npgsql"; + options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"); }).AddAdoNetGrainStorage("OrleansStorage", options => { - options.Invariant = "Npgsql"; - options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"); + options.Invariant = "Npgsql"; + options.ConnectionString = builder.Configuration.GetConnectionString("DefaultConnection"); }); if (builder.Environment.IsKube()) { - siloBuilder.UseKubeMembership().AddActivationRepartitioner().AddRedisStorage(IFusionSessionGrain.StorageId, 2) + siloBuilder + .UseKubeMembership() + .AddActivationRepartitioner() + .AddRedisStorage(IFusionSessionGrain.StorageId, 2) .AddPersistentStreams("default", NatsAdapterFactory.Create, options => { }) .AddPersistentStreams(IArgonEvent.ProviderId, NatsAdapterFactory.Create, options => { }); } else { - siloBuilder.UseLocalhostClustering().AddMemoryStreams("default").AddMemoryStreams(IArgonEvent.ProviderId) + siloBuilder + .UseLocalhostClustering() + .AddMemoryStreams("default") + .AddMemoryStreams(IArgonEvent.ProviderId) .AddMemoryGrainStorage(IFusionSessionGrain.StorageId); } }); diff --git a/src/Argon.Api/Features/Sentry/SentryOrleansFilter.cs b/src/Argon.Api/Features/Sentry/SentryOrleansFilter.cs new file mode 100644 index 0000000..1173fb1 --- /dev/null +++ b/src/Argon.Api/Features/Sentry/SentryOrleansFilter.cs @@ -0,0 +1,32 @@ +namespace Argon.Api.Features.Sentry; + +public class SentryGrainCallFilter : IIncomingGrainCallFilter +{ + public async Task Invoke(IIncomingGrainCallContext context) + { + try + { + await context.Invoke(); + } + catch (Exception ex) + { + SentrySdk.ConfigureScope(scope => + { + var grainId = context.TargetId.ToString(); + var calleGrain = context.SourceId?.ToString(); + var grainType = context.Grain.GetType().FullName; + + var methodName = context.ImplementationMethod.Name; + + if (!string.IsNullOrEmpty(calleGrain)) + scope.SetTag("ActivatorGrainId", calleGrain); + scope.SetTag("GrainId", grainId); + scope.SetTag("GrainType", grainType ?? "unk"); + scope.SetTag("MethodName", methodName); + }); + + SentrySdk.CaptureException(ex); + throw; + } + } +} \ No newline at end of file diff --git a/src/ServiceDefaults/Extensions.cs b/src/ServiceDefaults/Extensions.cs index a312595..6a62d10 100644 --- a/src/ServiceDefaults/Extensions.cs +++ b/src/ServiceDefaults/Extensions.cs @@ -9,7 +9,9 @@ namespace Microsoft.Extensions.Hosting; using OpenTelemetry; using OpenTelemetry.Metrics; using OpenTelemetry.Trace; +using Sentry.Extensibility; using Sentry.Infrastructure; +using Sentry.OpenTelemetry; // Adds common .NET Aspire services: service discovery, resilience, health checks, and OpenTelemetry. // This project should be referenced by each service project in your solution. @@ -58,6 +60,7 @@ public static IHostApplicationBuilder AddSentry(this WebApplicationBuilder build { EnableCodeLocations = true }; + o.UseOpenTelemetry(); }); return builder; @@ -71,6 +74,7 @@ public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicati logging.IncludeFormattedMessage = true; logging.IncludeScopes = true; }); + builder.Logging.AddSentry(); builder.Services.AddOpenTelemetry().WithMetrics(metrics => { @@ -80,7 +84,8 @@ public static IHostApplicationBuilder ConfigureOpenTelemetry(this IHostApplicati tracing.AddAspNetCoreInstrumentation() // Uncomment the following line to enable gRPC instrumentation (requires the OpenTelemetry.Instrumentation.GrpcNetClient package) //.AddGrpcClientInstrumentation() - .AddHttpClientInstrumentation(); + .AddHttpClientInstrumentation() + .AddSentry(); }); builder.AddOpenTelemetryExporters(); diff --git a/src/ServiceDefaults/ServiceDefaults.csproj b/src/ServiceDefaults/ServiceDefaults.csproj index 58d7d82..f5d89b8 100644 --- a/src/ServiceDefaults/ServiceDefaults.csproj +++ b/src/ServiceDefaults/ServiceDefaults.csproj @@ -21,6 +21,7 @@ + - + \ No newline at end of file