From 8fe982d8857fe5e982d8115aafba00ac2130841a Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Tue, 14 Nov 2023 19:05:18 +0100 Subject: [PATCH 1/6] apply scope to transactions --- src/Sentry/SentryClient.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Sentry/SentryClient.cs b/src/Sentry/SentryClient.cs index 23794cf049..8fb39624f5 100644 --- a/src/Sentry/SentryClient.cs +++ b/src/Sentry/SentryClient.cs @@ -98,10 +98,10 @@ public void CaptureUserFeedback(UserFeedback userFeedback) } /// - public void CaptureTransaction(Transaction transaction) => CaptureTransaction(transaction, null); + public void CaptureTransaction(Transaction transaction) => CaptureTransaction(transaction, null, null); /// - public void CaptureTransaction(Transaction transaction, Hint? hint) + public void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint) { if (transaction.SpanId.Equals(SpanId.Empty)) { @@ -137,7 +137,16 @@ public void CaptureTransaction(Transaction transaction, Hint? hint) return; } - var processedTransaction = BeforeSendTransaction(transaction, hint ?? new Hint()); + scope ??= new Scope(_options); + hint ??= new Hint(); + hint.AddAttachmentsFromScope(scope); + + _options.LogInfo("Capturing transaction."); + + scope.Evaluate(); + scope.Apply(transaction); + + var processedTransaction = BeforeSendTransaction(transaction, hint); if (processedTransaction is null) // Rejected transaction { _options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.BeforeSend, DataCategory.Transaction); From 4acdb9825c971606c04fd1d9116d1aeef04a236b Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Wed, 15 Nov 2023 22:29:27 +0100 Subject: [PATCH 2/6] . --- src/Sentry/Extensibility/DisabledHub.cs | 2 +- src/Sentry/Extensibility/HubAdapter.cs | 4 +- src/Sentry/ISentryClient.cs | 3 +- src/Sentry/Internal/Hub.cs | 38 ++------- src/Sentry/SentryClient.cs | 24 +++++- src/Sentry/SentrySdk.cs | 4 +- .../SentryTracingMiddlewareTests.cs | 7 +- .../SentryFunctionsWorkerMiddlewareTests.cs | 2 +- ...piApprovalTests.Run.DotNet6_0.verified.txt | 10 +-- ...piApprovalTests.Run.DotNet7_0.verified.txt | 10 +-- ...piApprovalTests.Run.DotNet8_0.verified.txt | 10 +-- .../ApiApprovalTests.Run.Net4_8.verified.txt | 10 +-- test/Sentry.Tests/HubTests.cs | 71 +--------------- .../Sentry.Tests/Protocol/MeasurementTests.cs | 8 ++ .../Sentry.Tests/Protocol/TransactionTests.cs | 2 +- test/Sentry.Tests/SentryClientTests.cs | 83 ++++++++++++++++++- 16 files changed, 153 insertions(+), 135 deletions(-) diff --git a/src/Sentry/Extensibility/DisabledHub.cs b/src/Sentry/Extensibility/DisabledHub.cs index f141150ca6..c8decb664c 100644 --- a/src/Sentry/Extensibility/DisabledHub.cs +++ b/src/Sentry/Extensibility/DisabledHub.cs @@ -158,7 +158,7 @@ public void CaptureTransaction(Transaction transaction) /// /// No-Op. /// - public void CaptureTransaction(Transaction transaction, Hint? hint) + public void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint) { } diff --git a/src/Sentry/Extensibility/HubAdapter.cs b/src/Sentry/Extensibility/HubAdapter.cs index a53c010c3f..ffe1992cc3 100644 --- a/src/Sentry/Extensibility/HubAdapter.cs +++ b/src/Sentry/Extensibility/HubAdapter.cs @@ -252,8 +252,8 @@ public void CaptureTransaction(Transaction transaction) /// [DebuggerStepThrough] [EditorBrowsable(EditorBrowsableState.Never)] - public void CaptureTransaction(Transaction transaction, Hint? hint) - => SentrySdk.CaptureTransaction(transaction, hint); + public void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint) + => SentrySdk.CaptureTransaction(transaction, scope, hint); /// /// Forwards the call to . diff --git a/src/Sentry/ISentryClient.cs b/src/Sentry/ISentryClient.cs index b4bbaef39f..384624fe5e 100644 --- a/src/Sentry/ISentryClient.cs +++ b/src/Sentry/ISentryClient.cs @@ -44,12 +44,13 @@ public interface ISentryClient /// Instead, call on the transaction. /// /// The transaction. + /// The scope to be applied to the transaction /// /// A hint providing extra context. /// This will be available in callbacks prior to processing the transaction. /// [EditorBrowsable(EditorBrowsableState.Never)] - void CaptureTransaction(Transaction transaction, Hint? hint); + void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint); /// /// Captures a session update. diff --git a/src/Sentry/Internal/Hub.cs b/src/Sentry/Internal/Hub.cs index ed6f4ef393..c0bb18e844 100644 --- a/src/Sentry/Internal/Hub.cs +++ b/src/Sentry/Internal/Hub.cs @@ -14,7 +14,6 @@ internal class Hub : IHub, IDisposable private readonly ISessionManager _sessionManager; private readonly SentryOptions _options; private readonly RandomValuesFactory _randomValuesFactory; - private readonly Enricher _enricher; private int _isPersistedSessionRecovered; @@ -59,8 +58,6 @@ internal class Hub : IHub, IDisposable PushScope(); } - _enricher = new Enricher(options); - foreach (var integration in options.Integrations) { options.LogDebug("Registering integration: '{0}'.", integration.GetType().Name); @@ -458,9 +455,9 @@ public void CaptureUserFeedback(UserFeedback userFeedback) } } - public void CaptureTransaction(Transaction transaction) => CaptureTransaction(transaction, null); + public void CaptureTransaction(Transaction transaction) => CaptureTransaction(transaction, null, null); - public void CaptureTransaction(Transaction transaction, Hint? hint) + public void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint) { // Note: The hub should capture transactions even if it is disabled. // This allows transactions to be reported as failed when they encountered an unhandled exception, @@ -473,34 +470,11 @@ public void CaptureTransaction(Transaction transaction, Hint? hint) try { - // Apply scope data - var (scope, client) = ScopeManager.GetCurrent(); - scope.Evaluate(); - scope.Apply(transaction); - - // Apply enricher - _enricher.Apply(transaction); - - // Add attachments to the hint for processors and callbacks - hint ??= new Hint(); - hint.AddAttachmentsFromScope(scope); - - var processedTransaction = transaction; - if (transaction.IsSampled != false) - { - foreach (var processor in scope.GetAllTransactionProcessors()) - { - processedTransaction = processor.DoProcessTransaction(transaction, hint); - if (processedTransaction == null) - { - _options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.EventProcessor, DataCategory.Transaction); - _options.LogInfo("Event dropped by processor {0}", processor.GetType().Name); - return; - } - } - } + var (currentScope, client) = ScopeManager.GetCurrent(); + // scope ??= currentScope; - client.CaptureTransaction(processedTransaction, hint); + client.CaptureTransaction(transaction, currentScope, hint); + Console.WriteLine("HALP!"); } catch (Exception e) { diff --git a/src/Sentry/SentryClient.cs b/src/Sentry/SentryClient.cs index 8fb39624f5..3f23429972 100644 --- a/src/Sentry/SentryClient.cs +++ b/src/Sentry/SentryClient.cs @@ -18,6 +18,7 @@ public class SentryClient : ISentryClient, IDisposable private readonly SentryOptions _options; private readonly ISessionManager _sessionManager; private readonly RandomValuesFactory _randomValuesFactory; + private readonly Enricher _enricher; internal IBackgroundWorker Worker { get; } internal SentryOptions Options => _options; @@ -44,6 +45,7 @@ public SentryClient(SentryOptions options) _options = options ?? throw new ArgumentNullException(nameof(options)); _randomValuesFactory = randomValuesFactory ?? new SynchronizedRandomValuesFactory(); _sessionManager = sessionManager ?? new GlobalSessionManager(options); + _enricher = new Enricher(options); options.SetupLogging(); // Only relevant if this client wasn't created as a result of calling Init @@ -127,8 +129,7 @@ public void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint } // Sampling decision MUST have been made at this point - Debug.Assert(transaction.IsSampled is not null, - "Attempt to capture transaction without sampling decision."); + Debug.Assert(transaction.IsSampled is not null, "Attempt to capture transaction without sampling decision."); if (transaction.IsSampled is false) { @@ -146,7 +147,24 @@ public void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint scope.Evaluate(); scope.Apply(transaction); - var processedTransaction = BeforeSendTransaction(transaction, hint); + _enricher.Apply(transaction); + + var processedTransaction = transaction; + if (transaction.IsSampled != false) + { + foreach (var processor in scope.GetAllTransactionProcessors()) + { + processedTransaction = processor.DoProcessTransaction(transaction, hint); + if (processedTransaction == null) + { + _options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.EventProcessor, DataCategory.Transaction); + _options.LogInfo("Event dropped by processor {0}", processor.GetType().Name); + return; + } + } + } + + processedTransaction = BeforeSendTransaction(processedTransaction, hint); if (processedTransaction is null) // Rejected transaction { _options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.BeforeSend, DataCategory.Transaction); diff --git a/src/Sentry/SentrySdk.cs b/src/Sentry/SentrySdk.cs index 1a2cbeff0c..294038090d 100644 --- a/src/Sentry/SentrySdk.cs +++ b/src/Sentry/SentrySdk.cs @@ -465,8 +465,8 @@ public static void CaptureTransaction(Transaction transaction) /// [DebuggerStepThrough] [EditorBrowsable(EditorBrowsableState.Never)] - public static void CaptureTransaction(Transaction transaction, Hint? hint) - => CurrentHub.CaptureTransaction(transaction, hint); + public static void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint) + => CurrentHub.CaptureTransaction(transaction, scope, hint); /// /// Captures a session update. diff --git a/test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs b/test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs index 27363282fe..8c2ad4aacc 100644 --- a/test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs +++ b/test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs @@ -56,6 +56,7 @@ public async Task Transactions_are_grouped_by_route() Arg.Is(transaction => transaction.Name == "GET /person/{id}" && transaction.NameSource == TransactionNameSource.Route), + Arg.Any(), Arg.Any() ); } @@ -151,6 +152,7 @@ public async Task Transaction_is_started_automatically_from_incoming_trace_heade t.ParentSpanId == SpanId.Parse("1000000000000000") && t.IsSampled == false ), + Arg.Any(), Arg.Any() ); } @@ -184,6 +186,7 @@ public async Task Transaction_name_includes_slash_prefix() Transaction transaction = null; sentryClient.CaptureTransaction( Arg.Do(t => transaction = t), + Arg.Any(), Arg.Any() ); @@ -598,7 +601,7 @@ public async Task Transaction_TransactionNameProviderSetSet_TransactionNameSet() var expectedName = "My custom name"; var sentryClient = Substitute.For(); - sentryClient.When(x => x.CaptureTransaction(Arg.Any(), Arg.Any())) + sentryClient.When(x => x.CaptureTransaction(Arg.Any(), Arg.Any(), Arg.Any())) .Do(callback => transaction = callback.Arg()); var options = new SentryAspNetCoreOptions { @@ -640,7 +643,7 @@ public async Task Transaction_TransactionNameProviderSetUnset_TransactionNameSet Transaction transaction = null; var sentryClient = Substitute.For(); - sentryClient.When(x => x.CaptureTransaction(Arg.Any(), Arg.Any())) + sentryClient.When(x => x.CaptureTransaction(Arg.Any(), Arg.Any(), Arg.Any())) .Do(callback => transaction = callback.Arg()); var options = new SentryAspNetCoreOptions { diff --git a/test/Sentry.Azure.Functions.Worker.Tests/SentryFunctionsWorkerMiddlewareTests.cs b/test/Sentry.Azure.Functions.Worker.Tests/SentryFunctionsWorkerMiddlewareTests.cs index bc37229524..b0aac44fa1 100644 --- a/test/Sentry.Azure.Functions.Worker.Tests/SentryFunctionsWorkerMiddlewareTests.cs +++ b/test/Sentry.Azure.Functions.Worker.Tests/SentryFunctionsWorkerMiddlewareTests.cs @@ -22,7 +22,7 @@ public Fixture() var client = Substitute.For(); var sessionManager = Substitute.For(); - client.When(x => x.CaptureTransaction(Arg.Any(), Arg.Any())) + client.When(x => x.CaptureTransaction(Arg.Any(), Arg.Any(), Arg.Any())) .Do(callback => Transaction = callback.Arg()); ScopeManager = new SentryScopeManager(options, client); diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt index 39648308f6..5adbdf4aa0 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet6_0.verified.txt @@ -251,7 +251,7 @@ namespace Sentry Sentry.SentryId CaptureEvent(Sentry.SentryEvent evt, Sentry.Scope? scope = null, Sentry.Hint? hint = null); void CaptureSession(Sentry.SessionUpdate sessionUpdate); void CaptureTransaction(Sentry.Transaction transaction); - void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint); + void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint); void CaptureUserFeedback(Sentry.UserFeedback userFeedback); System.Threading.Tasks.Task FlushAsync(System.TimeSpan timeout); } @@ -480,7 +480,7 @@ namespace Sentry public Sentry.SentryId CaptureEvent(Sentry.SentryEvent? @event, Sentry.Scope? scope = null, Sentry.Hint? hint = null) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } [System.Obsolete("Sentry client should not be explicitly disposed of. This method will be removed i" + "n version 4.")] @@ -737,7 +737,7 @@ namespace Sentry public static Sentry.SentryId CaptureMessage(string message, System.Action configureScope, Sentry.SentryLevel level = 1) { } public static void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public static void CaptureTransaction(Sentry.Transaction transaction) { } - public static void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public static void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public static void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } public static void CaptureUserFeedback(Sentry.SentryId eventId, string email, string comments, string? name = null) { } [System.Obsolete("WARNING: This method deliberately causes a crash, and should not be used in a rea" + @@ -1208,7 +1208,7 @@ namespace Sentry.Extensibility public Sentry.SentryId CaptureEvent(Sentry.SentryEvent evt, Sentry.Scope? scope = null, Sentry.Hint? hint = null) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } public void ConfigureScope(System.Action configureScope) { } public System.Threading.Tasks.Task ConfigureScopeAsync(System.Func configureScope) { } @@ -1250,7 +1250,7 @@ namespace Sentry.Extensibility public Sentry.SentryId CaptureException(System.Exception exception) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback sentryUserFeedback) { } public void ConfigureScope(System.Action configureScope) { } public System.Threading.Tasks.Task ConfigureScopeAsync(System.Func configureScope) { } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet7_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet7_0.verified.txt index 39648308f6..5adbdf4aa0 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet7_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet7_0.verified.txt @@ -251,7 +251,7 @@ namespace Sentry Sentry.SentryId CaptureEvent(Sentry.SentryEvent evt, Sentry.Scope? scope = null, Sentry.Hint? hint = null); void CaptureSession(Sentry.SessionUpdate sessionUpdate); void CaptureTransaction(Sentry.Transaction transaction); - void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint); + void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint); void CaptureUserFeedback(Sentry.UserFeedback userFeedback); System.Threading.Tasks.Task FlushAsync(System.TimeSpan timeout); } @@ -480,7 +480,7 @@ namespace Sentry public Sentry.SentryId CaptureEvent(Sentry.SentryEvent? @event, Sentry.Scope? scope = null, Sentry.Hint? hint = null) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } [System.Obsolete("Sentry client should not be explicitly disposed of. This method will be removed i" + "n version 4.")] @@ -737,7 +737,7 @@ namespace Sentry public static Sentry.SentryId CaptureMessage(string message, System.Action configureScope, Sentry.SentryLevel level = 1) { } public static void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public static void CaptureTransaction(Sentry.Transaction transaction) { } - public static void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public static void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public static void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } public static void CaptureUserFeedback(Sentry.SentryId eventId, string email, string comments, string? name = null) { } [System.Obsolete("WARNING: This method deliberately causes a crash, and should not be used in a rea" + @@ -1208,7 +1208,7 @@ namespace Sentry.Extensibility public Sentry.SentryId CaptureEvent(Sentry.SentryEvent evt, Sentry.Scope? scope = null, Sentry.Hint? hint = null) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } public void ConfigureScope(System.Action configureScope) { } public System.Threading.Tasks.Task ConfigureScopeAsync(System.Func configureScope) { } @@ -1250,7 +1250,7 @@ namespace Sentry.Extensibility public Sentry.SentryId CaptureException(System.Exception exception) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback sentryUserFeedback) { } public void ConfigureScope(System.Action configureScope) { } public System.Threading.Tasks.Task ConfigureScopeAsync(System.Func configureScope) { } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt index 39648308f6..5adbdf4aa0 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt @@ -251,7 +251,7 @@ namespace Sentry Sentry.SentryId CaptureEvent(Sentry.SentryEvent evt, Sentry.Scope? scope = null, Sentry.Hint? hint = null); void CaptureSession(Sentry.SessionUpdate sessionUpdate); void CaptureTransaction(Sentry.Transaction transaction); - void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint); + void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint); void CaptureUserFeedback(Sentry.UserFeedback userFeedback); System.Threading.Tasks.Task FlushAsync(System.TimeSpan timeout); } @@ -480,7 +480,7 @@ namespace Sentry public Sentry.SentryId CaptureEvent(Sentry.SentryEvent? @event, Sentry.Scope? scope = null, Sentry.Hint? hint = null) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } [System.Obsolete("Sentry client should not be explicitly disposed of. This method will be removed i" + "n version 4.")] @@ -737,7 +737,7 @@ namespace Sentry public static Sentry.SentryId CaptureMessage(string message, System.Action configureScope, Sentry.SentryLevel level = 1) { } public static void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public static void CaptureTransaction(Sentry.Transaction transaction) { } - public static void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public static void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public static void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } public static void CaptureUserFeedback(Sentry.SentryId eventId, string email, string comments, string? name = null) { } [System.Obsolete("WARNING: This method deliberately causes a crash, and should not be used in a rea" + @@ -1208,7 +1208,7 @@ namespace Sentry.Extensibility public Sentry.SentryId CaptureEvent(Sentry.SentryEvent evt, Sentry.Scope? scope = null, Sentry.Hint? hint = null) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } public void ConfigureScope(System.Action configureScope) { } public System.Threading.Tasks.Task ConfigureScopeAsync(System.Func configureScope) { } @@ -1250,7 +1250,7 @@ namespace Sentry.Extensibility public Sentry.SentryId CaptureException(System.Exception exception) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback sentryUserFeedback) { } public void ConfigureScope(System.Action configureScope) { } public System.Threading.Tasks.Task ConfigureScopeAsync(System.Func configureScope) { } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt index b74651c7f0..e0314208bd 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt @@ -250,7 +250,7 @@ namespace Sentry Sentry.SentryId CaptureEvent(Sentry.SentryEvent evt, Sentry.Scope? scope = null, Sentry.Hint? hint = null); void CaptureSession(Sentry.SessionUpdate sessionUpdate); void CaptureTransaction(Sentry.Transaction transaction); - void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint); + void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint); void CaptureUserFeedback(Sentry.UserFeedback userFeedback); System.Threading.Tasks.Task FlushAsync(System.TimeSpan timeout); } @@ -479,7 +479,7 @@ namespace Sentry public Sentry.SentryId CaptureEvent(Sentry.SentryEvent? @event, Sentry.Scope? scope = null, Sentry.Hint? hint = null) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } [System.Obsolete("Sentry client should not be explicitly disposed of. This method will be removed i" + "n version 4.")] @@ -734,7 +734,7 @@ namespace Sentry public static Sentry.SentryId CaptureMessage(string message, System.Action configureScope, Sentry.SentryLevel level = 1) { } public static void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public static void CaptureTransaction(Sentry.Transaction transaction) { } - public static void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public static void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public static void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } public static void CaptureUserFeedback(Sentry.SentryId eventId, string email, string comments, string? name = null) { } [System.Obsolete("WARNING: This method deliberately causes a crash, and should not be used in a rea" + @@ -1205,7 +1205,7 @@ namespace Sentry.Extensibility public Sentry.SentryId CaptureEvent(Sentry.SentryEvent evt, Sentry.Scope? scope = null, Sentry.Hint? hint = null) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback userFeedback) { } public void ConfigureScope(System.Action configureScope) { } public System.Threading.Tasks.Task ConfigureScopeAsync(System.Func configureScope) { } @@ -1247,7 +1247,7 @@ namespace Sentry.Extensibility public Sentry.SentryId CaptureException(System.Exception exception) { } public void CaptureSession(Sentry.SessionUpdate sessionUpdate) { } public void CaptureTransaction(Sentry.Transaction transaction) { } - public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Hint? hint) { } + public void CaptureTransaction(Sentry.Transaction transaction, Sentry.Scope? scope, Sentry.Hint? hint) { } public void CaptureUserFeedback(Sentry.UserFeedback sentryUserFeedback) { } public void ConfigureScope(System.Action configureScope) { } public System.Threading.Tasks.Task ConfigureScopeAsync(System.Func configureScope) { } diff --git a/test/Sentry.Tests/HubTests.cs b/test/Sentry.Tests/HubTests.cs index b88c7e0fc6..b79a5fb4fa 100644 --- a/test/Sentry.Tests/HubTests.cs +++ b/test/Sentry.Tests/HubTests.cs @@ -1309,7 +1309,7 @@ public void CaptureTransaction_HubEnabled(bool enabled) transaction.Finish(); // Assert - _fixture.Client.Received().CaptureTransaction(Arg.Is(t => t.IsSampled == enabled), Arg.Any()); + _fixture.Client.Received().CaptureTransaction(Arg.Is(t => t.IsSampled == enabled),Arg.Any(), Arg.Any()); } [Fact] @@ -1323,74 +1323,7 @@ public void CaptureTransaction_Client_Gets_Hint() transaction.Finish(); // Assert - _fixture.Client.Received().CaptureTransaction(Arg.Any(), Arg.Any()); - } - - [Fact] - public void CaptureTransaction_Client_Gets_ScopeAttachments() - { - // Arrange - var hub = _fixture.GetSut(); - var attachments = new List { - AttachmentHelper.FakeAttachment("foo"), - AttachmentHelper.FakeAttachment("bar") - }; - hub.ConfigureScope(s => { - s.AddAttachment(attachments[0]); - s.AddAttachment(attachments[1]); - }); - - // Act - Hint hint = null; - _fixture.Client.CaptureTransaction( - Arg.Any(), - Arg.Do(h => hint = h) - ); - var transaction = hub.StartTransaction("test", "test"); - transaction.Finish(); - - // Assert - hint.Should().NotBeNull(); - hint.Attachments.Should().Contain(attachments); - } - - [Fact] - public void CaptureTransaction_EventProcessor_Gets_Hint() - { - // Arrange - var processor = Substitute.For(); - processor.Process(Arg.Any(), Arg.Any()).Returns(new Transaction("name", "operation")); - _fixture.Options.AddTransactionProcessor(processor); - - // Act - var hub = _fixture.GetSut(); - var transaction = hub.StartTransaction("test", "test"); - transaction.Finish(); - - // Assert - processor.Received(1).Process(Arg.Any(), Arg.Any()); - } - - [Fact] - public void CaptureTransaction_EventProcessor_Gets_ScopeAttachments() - { - // Arrange - var processor = Substitute.For(); - Hint hint = null; - processor.Process(Arg.Any(), Arg.Do(h => hint = h)).Returns(new Transaction("name", "operation")); - _fixture.Options.AddTransactionProcessor(processor); - - var attachments = new List { AttachmentHelper.FakeAttachment("foo.txt") }; - var hub = _fixture.GetSut(); - hub.ConfigureScope(s => s.AddAttachment(attachments[0])); - - // Act - var transaction = hub.StartTransaction("test", "test"); - transaction.Finish(); - - // Assert - hint.Should().NotBeNull(); - hint.Attachments.Should().Contain(attachments); + _fixture.Client.Received().CaptureTransaction(Arg.Any(), Arg.Any(), Arg.Any()); } [Theory] diff --git a/test/Sentry.Tests/Protocol/MeasurementTests.cs b/test/Sentry.Tests/Protocol/MeasurementTests.cs index 762a74a9bb..bfeca3312a 100644 --- a/test/Sentry.Tests/Protocol/MeasurementTests.cs +++ b/test/Sentry.Tests/Protocol/MeasurementTests.cs @@ -187,6 +187,7 @@ public void Transaction_SetMeasurement_IntValue() t.Measurements.Count == 1 && t.Measurements["foo"].Value.As() == int.MaxValue && t.Measurements["foo"].Unit == EmptyUnit), + Arg.Any(), Arg.Any() ); } @@ -214,6 +215,7 @@ public void Transaction_SetMeasurement_LongValue() t.Measurements.Count == 1 && t.Measurements["foo"].Value.As() == long.MaxValue && t.Measurements["foo"].Unit == EmptyUnit), + Arg.Any(), Arg.Any() ); } @@ -241,6 +243,7 @@ public void Transaction_SetMeasurement_ULongValue() t.Measurements.Count == 1 && t.Measurements["foo"].Value.As() == ulong.MaxValue && t.Measurements["foo"].Unit == EmptyUnit), + Arg.Any(), Arg.Any() ); } @@ -268,6 +271,7 @@ public void Transaction_SetMeasurement_DoubleValue() t.Measurements.Count == 1 && Math.Abs(t.Measurements["foo"].Value.As() - double.MaxValue) < double.Epsilon && t.Measurements["foo"].Unit == EmptyUnit), + Arg.Any(), Arg.Any() ); } @@ -295,6 +299,7 @@ public void Transaction_SetMeasurement_IntValue_WithUnit() t.Measurements.Count == 1 && t.Measurements["foo"].Value.As() == int.MaxValue && t.Measurements["foo"].Unit == MeasurementUnit.Duration.Nanosecond), + Arg.Any(), Arg.Any() ); } @@ -322,6 +327,7 @@ public void Transaction_SetMeasurement_LongValue_WithUnit() t.Measurements.Count == 1 && t.Measurements["foo"].Value.As() == long.MaxValue && t.Measurements["foo"].Unit == MeasurementUnit.Duration.Nanosecond), + Arg.Any(), Arg.Any() ); } @@ -349,6 +355,7 @@ public void Transaction_SetMeasurement_ULongValue_WithUnit() t.Measurements.Count == 1 && t.Measurements["foo"].Value.As() == ulong.MaxValue && t.Measurements["foo"].Unit == MeasurementUnit.Duration.Nanosecond), + Arg.Any(), Arg.Any() ); } @@ -376,6 +383,7 @@ public void Transaction_SetMeasurement_DoubleValue_WithUnit() t.Measurements.Count == 1 && Math.Abs(t.Measurements["foo"].Value.As() - double.MaxValue) < double.Epsilon && t.Measurements["foo"].Unit == MeasurementUnit.Duration.Nanosecond), + Arg.Any(), Arg.Any() ); } diff --git a/test/Sentry.Tests/Protocol/TransactionTests.cs b/test/Sentry.Tests/Protocol/TransactionTests.cs index ff70d36546..0b5802f3a7 100644 --- a/test/Sentry.Tests/Protocol/TransactionTests.cs +++ b/test/Sentry.Tests/Protocol/TransactionTests.cs @@ -472,7 +472,7 @@ public void Finish_CapturesTransaction() transaction.Finish(); // Assert - client.Received(1).CaptureTransaction(Arg.Any(), Arg.Any()); + client.Received(1).CaptureTransaction(Arg.Any(), Arg.Any(), Arg.Any()); } [Fact] diff --git a/test/Sentry.Tests/SentryClientTests.cs b/test/Sentry.Tests/SentryClientTests.cs index d2b8bfa990..a38293e536 100644 --- a/test/Sentry.Tests/SentryClientTests.cs +++ b/test/Sentry.Tests/SentryClientTests.cs @@ -986,6 +986,87 @@ public void CaptureTransaction_BeforeSendTransaction_RejectEvent() _ = _fixture.BackgroundWorker.DidNotReceive().EnqueueEnvelope(Arg.Any()); } + [Fact] + public void CaptureTransaction_ScopeContainsAttachments_GetAppliedToHint() + { + // Arrange + var transaction = new Transaction("name", "operation") + { + IsSampled = true, + EndTimestamp = DateTimeOffset.Now // finished + }; + var attachments = new List { + AttachmentHelper.FakeAttachment("foo"), + AttachmentHelper.FakeAttachment("bar") + }; + var scope = new Scope(_fixture.SentryOptions); + scope.AddAttachment(attachments[0]); + scope.AddAttachment(attachments[1]); + + Hint hint = null; + _fixture.SentryOptions.SetBeforeSendTransaction((e, h) => { + hint = h; + return e; + }); + + // Act + _fixture.GetSut().CaptureTransaction( + transaction, + scope, + hint + ); + + // Assert + hint.Should().NotBeNull(); + hint.Attachments.Should().Contain(attachments); + } + + [Fact] + public void CaptureTransaction_TransactionProcessor_ReceivesHint() + { + // Arrange + var processor = Substitute.For(); + processor.Process(Arg.Any(), Arg.Any()).Returns(new Transaction("name", "operation")); + _fixture.SentryOptions.AddTransactionProcessor(processor); + + var transaction = new Transaction("name", "operation") + { + IsSampled = true, + EndTimestamp = DateTimeOffset.Now // finished + }; + + // Act + _fixture.GetSut().CaptureTransaction(transaction); + + // Assert + processor.Received(1).Process(Arg.Any(), Arg.Any()); + } + + [Fact] + public void CaptureTransaction_TransactionProcessor_ReceivesScopeAttachments() + { + // Arrange + var processor = Substitute.For(); + Hint hint = null; + processor.Process( + Arg.Any(), + Arg.Do(h => hint = h)) + .Returns(new Transaction("name", "operation")); + _fixture.SentryOptions.AddTransactionProcessor(processor); + + var attachments = new List { AttachmentHelper.FakeAttachment("foo.txt") }; + var hub = _fixture.GetSut(); + hub.ConfigureScope(s => s.AddAttachment(attachments[0])); + + // Act + var transaction = hub.StartTransaction("test", "test"); + transaction.Finish(); + + // Assert + hint.Should().NotBeNull(); + hint.Attachments.Should().Contain(attachments); + } + [Fact] public void CaptureTransaction_BeforeSendTransaction_GetsHint() { @@ -1004,7 +1085,7 @@ public void CaptureTransaction_BeforeSendTransaction_GetsHint() var sut = _fixture.GetSut(); var hint = new Hint(); - sut.CaptureTransaction(transaction, hint); + sut.CaptureTransaction(transaction, null, hint); Assert.Same(hint, received); } From ecf42fd36817d23336dea55401823f863a537e7f Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 16 Nov 2023 14:59:58 +0100 Subject: [PATCH 3/6] tests --- .../SentryTracingMiddlewareTests.cs | 4 +--- .../SentryLoggingOptionsSetupTests.cs | 4 ++-- test/Sentry.Tests/SentryClientTests.cs | 22 ++++++++++--------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs b/test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs index 8c2ad4aacc..1151a6bd03 100644 --- a/test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs +++ b/test/Sentry.AspNetCore.Tests/SentryTracingMiddlewareTests.cs @@ -440,9 +440,7 @@ public async Task Transaction_is_automatically_populated_with_request_data() // Arrange ITransactionData transaction = null; - var sentryClient = Substitute.For(); - - var hub = new Hub(new SentryOptions { Dsn = ValidDsn, TracesSampleRate = 1 }, sentryClient); + var hub = new Hub(new SentryOptions { Dsn = ValidDsn, TracesSampleRate = 1 }); var server = new TestServer(new WebHostBuilder() .UseDefaultServiceProvider(di => di.EnableValidation()) diff --git a/test/Sentry.Extensions.Logging.Tests/SentryLoggingOptionsSetupTests.cs b/test/Sentry.Extensions.Logging.Tests/SentryLoggingOptionsSetupTests.cs index 12b91b084b..4660ec85d0 100644 --- a/test/Sentry.Extensions.Logging.Tests/SentryLoggingOptionsSetupTests.cs +++ b/test/Sentry.Extensions.Logging.Tests/SentryLoggingOptionsSetupTests.cs @@ -70,7 +70,7 @@ public void Configure_BindsConfigurationToOptions() ["ServerName"] = expected.ServerName, ["AttachStacktrace"] = expected.AttachStacktrace.ToString(), ["MaxBreadcrumbs"] = expected.MaxBreadcrumbs.ToString(), - ["SampleRate"] = expected.SampleRate.ToString(), + ["SampleRate"] = expected.SampleRate.Value.ToString(CultureInfo.InvariantCulture), ["Release"] = expected.Release, ["Distribution"] = expected.Distribution, ["Environment"] = expected.Environment, @@ -95,7 +95,7 @@ public void Configure_BindsConfigurationToOptions() ["InitCacheFlushTimeout"] = expected.InitCacheFlushTimeout.ToString(), ["DefaultTags"] = expected.DefaultTags.ToString(), ["EnableTracing"] = expected.EnableTracing.ToString(), - ["TracesSampleRate"] = expected.TracesSampleRate.ToString(), + ["TracesSampleRate"] = expected.TracesSampleRate.Value.ToString(CultureInfo.InvariantCulture), ["TracePropagationTargets:0"] = expected.TracePropagationTargets.First().ToString(), ["TracePropagationTargets:1"] = expected.TracePropagationTargets.Last().ToString(), ["StackTraceMode"] = expected.StackTraceMode.ToString(), diff --git a/test/Sentry.Tests/SentryClientTests.cs b/test/Sentry.Tests/SentryClientTests.cs index a38293e536..0305ea1949 100644 --- a/test/Sentry.Tests/SentryClientTests.cs +++ b/test/Sentry.Tests/SentryClientTests.cs @@ -1010,11 +1010,7 @@ public void CaptureTransaction_ScopeContainsAttachments_GetAppliedToHint() }); // Act - _fixture.GetSut().CaptureTransaction( - transaction, - scope, - hint - ); + _fixture.GetSut().CaptureTransaction(transaction, scope, hint); // Assert hint.Should().NotBeNull(); @@ -1022,7 +1018,7 @@ public void CaptureTransaction_ScopeContainsAttachments_GetAppliedToHint() } [Fact] - public void CaptureTransaction_TransactionProcessor_ReceivesHint() + public void CaptureTransaction_AddedTransactionProcessor_ReceivesHint() { // Arrange var processor = Substitute.For(); @@ -1046,6 +1042,12 @@ public void CaptureTransaction_TransactionProcessor_ReceivesHint() public void CaptureTransaction_TransactionProcessor_ReceivesScopeAttachments() { // Arrange + var transaction = new Transaction("name", "operation") + { + IsSampled = true, + EndTimestamp = DateTimeOffset.Now // finished + }; + var processor = Substitute.For(); Hint hint = null; processor.Process( @@ -1055,12 +1057,12 @@ public void CaptureTransaction_TransactionProcessor_ReceivesScopeAttachments() _fixture.SentryOptions.AddTransactionProcessor(processor); var attachments = new List { AttachmentHelper.FakeAttachment("foo.txt") }; - var hub = _fixture.GetSut(); - hub.ConfigureScope(s => s.AddAttachment(attachments[0])); + var scope = new Scope(_fixture.SentryOptions); + scope.AddAttachment(attachments[0]); // Act - var transaction = hub.StartTransaction("test", "test"); - transaction.Finish(); + var client = _fixture.GetSut(); + client.CaptureTransaction(transaction, scope, null); // Assert hint.Should().NotBeNull(); From 5a126f277b42789bf46e4d2decd075977aeaae7f Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Thu, 16 Nov 2023 20:07:10 +0100 Subject: [PATCH 4/6] removed debug stuff --- src/Sentry/Internal/Hub.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Sentry/Internal/Hub.cs b/src/Sentry/Internal/Hub.cs index c0bb18e844..79b7c11cb5 100644 --- a/src/Sentry/Internal/Hub.cs +++ b/src/Sentry/Internal/Hub.cs @@ -471,10 +471,9 @@ public void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint try { var (currentScope, client) = ScopeManager.GetCurrent(); - // scope ??= currentScope; + scope ??= currentScope; - client.CaptureTransaction(transaction, currentScope, hint); - Console.WriteLine("HALP!"); + client.CaptureTransaction(transaction, scope, hint); } catch (Exception e) { From 5ca7c86daa49fea7d9d6af389b99a4930c370d9f Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 17 Nov 2023 12:35:18 +0100 Subject: [PATCH 5/6] cleanup --- src/Sentry/SentryClient.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Sentry/SentryClient.cs b/src/Sentry/SentryClient.cs index f9e45340bc..8bff75169b 100644 --- a/src/Sentry/SentryClient.cs +++ b/src/Sentry/SentryClient.cs @@ -150,17 +150,14 @@ public void CaptureTransaction(Transaction transaction, Scope? scope, Hint? hint _enricher.Apply(transaction); var processedTransaction = transaction; - if (transaction.IsSampled != false) + foreach (var processor in scope.GetAllTransactionProcessors()) { - foreach (var processor in scope.GetAllTransactionProcessors()) + processedTransaction = processor.DoProcessTransaction(transaction, hint); + if (processedTransaction == null) // Rejected transaction { - processedTransaction = processor.DoProcessTransaction(transaction, hint); - if (processedTransaction == null) - { - _options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.EventProcessor, DataCategory.Transaction); - _options.LogInfo("Event dropped by processor {0}", processor.GetType().Name); - return; - } + _options.ClientReportRecorder.RecordDiscardedEvent(DiscardReason.EventProcessor, DataCategory.Transaction); + _options.LogInfo("Event dropped by processor {0}", processor.GetType().Name); + return; } } From b0890f20a26a59b61dcf31b92998eafc3dc45db4 Mon Sep 17 00:00:00 2001 From: bitsandfoxes Date: Fri, 17 Nov 2023 12:40:59 +0100 Subject: [PATCH 6/6] Updated CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6599c21207..304ffd8dc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Fixes - Don't add WinUI exception integration on mobile platforms ([#2821](https://github.com/getsentry/sentry-dotnet/pull/2821)) +- `Transactions` are now getting enriched by the client instead of the hub ([#2838](https://github.com/getsentry/sentry-dotnet/pull/2838)) ### API breaking Changes