diff --git a/src/Sentry.Profiling/SampleProfileBuilder.cs b/src/Sentry.Profiling/SampleProfileBuilder.cs index 56927be4a9..bdef768d85 100644 --- a/src/Sentry.Profiling/SampleProfileBuilder.cs +++ b/src/Sentry.Profiling/SampleProfileBuilder.cs @@ -16,12 +16,8 @@ internal class SampleProfileBuilder // Output profile being built. public readonly SampleProfile Profile = new(); - // A sparse array that maps from CodeAddressIndex to an index in the output Profile.frames. - private readonly Dictionary _frameIndexesByCodeAddressIndex = new(); - - // A sparse array that maps from MethodIndex to an index in the output Profile.frames. - // This deduplicates frames that map to the same method but have a different CodeAddressIndex. - private readonly Dictionary _frameIndexesByMethodIndex = new(); + // A sparse array that maps from StackSourceFrameIndex to an index in the output Profile.frames. + private readonly Dictionary _frameIndexes = new(); // A dictionary from a CallStackIndex to an index in the output Profile.stacks. private readonly Dictionary _stackIndexes = new(); @@ -89,14 +85,13 @@ private int AddStackTrace(CallStackIndex callstackIndex) { var key = (int)callstackIndex; - if (!_stackIndexes.TryGetValue(key, out var value)) + if (!_stackIndexes.ContainsKey(key)) { Profile.Stacks.Add(CreateStackTrace(callstackIndex)); - value = Profile.Stacks.Count - 1; - _stackIndexes[key] = value; + _stackIndexes[key] = Profile.Stacks.Count - 1; } - return value; + return _stackIndexes[key]; } private Internal.GrowableArray CreateStackTrace(CallStackIndex callstackIndex) @@ -121,71 +116,21 @@ private Internal.GrowableArray CreateStackTrace(CallStackIndex callstackInd return stackTrace; } - private int PushNewFrame(SentryStackFrame frame) - { - Profile.Frames.Add(frame); - return Profile.Frames.Count - 1; - } - /// /// Check if the frame is already stored in the output Profile, or adds it. /// /// The index to the output Profile frames array. private int AddStackFrame(CodeAddressIndex codeAddressIndex) { - if (_frameIndexesByCodeAddressIndex.TryGetValue((int)codeAddressIndex, out var value)) - { - return value; - } + var key = (int)codeAddressIndex; - var methodIndex = _traceLog.CodeAddresses.MethodIndex(codeAddressIndex); - if (methodIndex != MethodIndex.Invalid) - { - value = AddStackFrame(methodIndex); - _frameIndexesByCodeAddressIndex[(int)codeAddressIndex] = value; - return value; - } - - // Fall back if the method info is unknown, see more info on Symbol resolution in - // https://github.com/getsentry/perfview/blob/031250ffb4f9fcadb9263525d6c9f274be19ca51/src/PerfView/SupportFiles/UsersGuide.htm#L7745-L7784 - if (_traceLog.CodeAddresses[codeAddressIndex] is { } codeAddressInfo) + if (!_frameIndexes.ContainsKey(key)) { - var frame = new SentryStackFrame - { - InstructionAddress = (long?)codeAddressInfo.Address, - Module = codeAddressInfo.ModuleFile?.Name, - }; - frame.ConfigureAppFrame(_options); - - return _frameIndexesByCodeAddressIndex[(int)codeAddressIndex] = PushNewFrame(frame); + Profile.Frames.Add(CreateStackFrame(codeAddressIndex)); + _frameIndexes[key] = Profile.Frames.Count - 1; } - // If all else fails, it's a completely unknown frame. - // TODO check this - maybe we would be able to resolve it later in the future? - return PushNewFrame(new SentryStackFrame { InApp = false }); - } - - /// - /// Check if the frame is already stored in the output Profile, or adds it. - /// - /// The index to the output Profile frames array. - private int AddStackFrame(MethodIndex methodIndex) - { - if (_frameIndexesByMethodIndex.TryGetValue((int)methodIndex, out var value)) - { - return value; - } - - var method = _traceLog.CodeAddresses.Methods[methodIndex]; - - var frame = new SentryStackFrame - { - Function = method.FullMethodName, - Module = method.MethodModuleFile?.Name - }; - frame.ConfigureAppFrame(_options); - - return _frameIndexesByMethodIndex[(int)methodIndex] = PushNewFrame(frame); + return _frameIndexes[key]; } /// @@ -196,17 +141,52 @@ private int AddThread(TraceThread thread) { var key = (int)thread.ThreadIndex; - if (!_threadIndexes.TryGetValue(key, out var value)) + if (!_threadIndexes.ContainsKey(key)) { Profile.Threads.Add(new() { Name = thread.ThreadInfo ?? $"Thread {thread.ThreadID}", }); - value = Profile.Threads.Count - 1; - _threadIndexes[key] = value; + _threadIndexes[key] = Profile.Threads.Count - 1; _downsampler.NewThreadAdded(_threadIndexes[key]); } - return value; + return _threadIndexes[key]; + } + + private SentryStackFrame CreateStackFrame(CodeAddressIndex codeAddressIndex) + { + var frame = new SentryStackFrame(); + + var methodIndex = _traceLog.CodeAddresses.MethodIndex(codeAddressIndex); + if (_traceLog.CodeAddresses.Methods[methodIndex] is { } method) + { + frame.Function = method.FullMethodName; + + if (method.MethodModuleFile is { } moduleFile) + { + frame.Module = moduleFile.Name; + } + + frame.ConfigureAppFrame(_options); + } + else + { + // Fall back if the method info is unknown, see more info on Symbol resolution in + // https://github.com/getsentry/perfview/blob/031250ffb4f9fcadb9263525d6c9f274be19ca51/src/PerfView/SupportFiles/UsersGuide.htm#L7745-L7784 + frame.InstructionAddress = (long?)_traceLog.CodeAddresses.Address(codeAddressIndex); + + if (_traceLog.CodeAddresses.ModuleFile(codeAddressIndex) is { } moduleFile) + { + frame.Module = moduleFile.Name; + frame.ConfigureAppFrame(_options); + } + else + { + frame.InApp = false; + } + } + + return frame; } } diff --git a/src/Sentry.Profiling/SampleProfilerSession.cs b/src/Sentry.Profiling/SampleProfilerSession.cs index 6cd9a9242a..3bb606a960 100644 --- a/src/Sentry.Profiling/SampleProfilerSession.cs +++ b/src/Sentry.Profiling/SampleProfilerSession.cs @@ -12,32 +12,31 @@ namespace Sentry.Profiling; internal class SampleProfilerSession : IDisposable { private readonly EventPipeSession _session; + private readonly TraceLogEventSource _eventSource; private readonly SampleProfilerTraceEventParser _sampleEventParser; private readonly IDiagnosticLogger? _logger; private readonly SentryStopwatch _stopwatch; private bool _stopped = false; - private Task _processing; - private SampleProfilerSession(SentryStopwatch stopwatch, EventPipeSession session, TraceLogEventSource eventSource, Task processing, IDiagnosticLogger? logger) + private SampleProfilerSession(SentryStopwatch stopwatch, EventPipeSession session, TraceLogEventSource eventSource, IDiagnosticLogger? logger) { _session = session; _logger = logger; - EventSource = eventSource; - _sampleEventParser = new SampleProfilerTraceEventParser(EventSource); + _eventSource = eventSource; + _sampleEventParser = new SampleProfilerTraceEventParser(_eventSource); _stopwatch = stopwatch; - _processing = processing; } // Exposed only for benchmarks. internal static EventPipeProvider[] Providers = new[] { - new EventPipeProvider(ClrTraceEventParser.ProviderName, EventLevel.Verbose, (long) ( - ClrTraceEventParser.Keywords.Jit - | ClrTraceEventParser.Keywords.NGen - | ClrTraceEventParser.Keywords.Loader - | ClrTraceEventParser.Keywords.Binder - | ClrTraceEventParser.Keywords.JittedMethodILToNativeMap - )), + // Note: all events we need issued by "DotNETRuntime" provider are at "EventLevel.Informational" + // see https://learn.microsoft.com/en-us/dotnet/fundamentals/diagnostics/runtime-events + // TODO replace Keywords.Default with a subset. Currently it is: + // Default = GC | Type | GCHeapSurvivalAndMovement | Binder | Loader | Jit | NGen | SupressNGen + // | StopEnumeration | Security | AppDomainResourceManagement | Exception | Threading | Contention | Stack | JittedMethodILToNativeMap + // | ThreadTransfer | GCHeapAndTypeNames | Codesymbols | Compilation, + new EventPipeProvider(ClrTraceEventParser.ProviderName, EventLevel.Informational, (long) ClrTraceEventParser.Keywords.Default), new EventPipeProvider(SampleProfilerTraceEventParser.ProviderName, EventLevel.Informational), // new EventPipeProvider(TplEtwProviderTraceEventParser.ProviderName, EventLevel.Informational, (long) TplEtwProviderTraceEventParser.Keywords.Default) }; @@ -47,14 +46,11 @@ private SampleProfilerSession(SentryStopwatch stopwatch, EventPipeSession sessio // need a large buffer if we're connecting righ away. Leaving it too large increases app memory usage. internal static int CircularBufferMB = 16; - // Exposed for tests - internal TraceLogEventSource EventSource { get; } - public SampleProfilerTraceEventParser SampleEventParser => _sampleEventParser; public TimeSpan Elapsed => _stopwatch.Elapsed; - public TraceLog TraceLog => EventSource.TraceLog; + public TraceLog TraceLog => _eventSource.TraceLog; // default is false, set 1 for true. private static int _throwOnNextStartupForTests = 0; @@ -90,7 +86,7 @@ public static SampleProfilerSession StartNew(IDiagnosticLogger? logger = null) var eventSource = TraceLog.CreateFromEventPipeSession(session, TraceLog.EventPipeRundownConfiguration.Enable(client)); // Process() blocks until the session is stopped so we need to run it on a separate thread. - var processing = Task.Factory.StartNew(eventSource.Process, TaskCreationOptions.LongRunning) + Task.Factory.StartNew(eventSource.Process, TaskCreationOptions.LongRunning) .ContinueWith(_ => { if (_.Exception?.InnerException is { } e) @@ -99,7 +95,7 @@ public static SampleProfilerSession StartNew(IDiagnosticLogger? logger = null) } }, TaskContinuationOptions.OnlyOnFaulted); - return new SampleProfilerSession(stopWatch, session, eventSource, processing, logger); + return new SampleProfilerSession(stopWatch, session, eventSource, logger); } catch (Exception ex) { @@ -112,7 +108,7 @@ public async Task WaitForFirstEventAsync(CancellationToken cancellationToken = d { var tcs = new TaskCompletionSource(); var cb = (TraceEvent _) => { tcs.TrySetResult(); }; - EventSource.AllEvents += cb; + _eventSource.AllEvents += cb; try { // Wait for the first event to be processed. @@ -120,7 +116,7 @@ public async Task WaitForFirstEventAsync(CancellationToken cancellationToken = d } finally { - EventSource.AllEvents -= cb; + _eventSource.AllEvents -= cb; } } @@ -132,9 +128,8 @@ public void Stop() { _stopped = true; _session.Stop(); - _processing.Wait(); _session.Dispose(); - EventSource.Dispose(); + _eventSource.Dispose(); } catch (Exception ex) { diff --git a/src/Sentry.Profiling/Sentry.Profiling.csproj b/src/Sentry.Profiling/Sentry.Profiling.csproj index 9413ef51f0..c453876242 100644 --- a/src/Sentry.Profiling/Sentry.Profiling.csproj +++ b/src/Sentry.Profiling/Sentry.Profiling.csproj @@ -14,7 +14,7 @@ - + diff --git a/test/Sentry.AspNetCore.Tests/WebIntegrationTests.Versioning.DotNet8_0.verified.txt b/test/Sentry.AspNetCore.Tests/WebIntegrationTests.Versioning.DotNet8_0.verified.txt index f60140240c..019cc1fb2d 100644 --- a/test/Sentry.AspNetCore.Tests/WebIntegrationTests.Versioning.DotNet8_0.verified.txt +++ b/test/Sentry.AspNetCore.Tests/WebIntegrationTests.Versioning.DotNet8_0.verified.txt @@ -73,10 +73,6 @@ Category: Microsoft.AspNetCore.Routing.EndpointMiddleware } ], - Extra: { - http.request.method: GET, - http.response.status_code: 200 - }, Tags: { ActionId: Guid_2, ActionName: Sentry.AspNetCore.Tests.WebIntegrationTests+VersionController.Method (Sentry.AspNetCore.Tests), diff --git a/test/Sentry.AspNetCore.Tests/WebIntegrationTests.Versioning.DotNet9_0.verified.txt b/test/Sentry.AspNetCore.Tests/WebIntegrationTests.Versioning.DotNet9_0.verified.txt index f60140240c..019cc1fb2d 100644 --- a/test/Sentry.AspNetCore.Tests/WebIntegrationTests.Versioning.DotNet9_0.verified.txt +++ b/test/Sentry.AspNetCore.Tests/WebIntegrationTests.Versioning.DotNet9_0.verified.txt @@ -73,10 +73,6 @@ Category: Microsoft.AspNetCore.Routing.EndpointMiddleware } ], - Extra: { - http.request.method: GET, - http.response.status_code: 200 - }, Tags: { ActionId: Guid_2, ActionName: Sentry.AspNetCore.Tests.WebIntegrationTests+VersionController.Method (Sentry.AspNetCore.Tests), diff --git a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.LoggingAsync.DotNet8_0.verified.txt b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.LoggingAsync.DotNet8_0.verified.txt index 298823718c..348b185b6f 100644 --- a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.LoggingAsync.DotNet8_0.verified.txt +++ b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.LoggingAsync.DotNet8_0.verified.txt @@ -27,7 +27,7 @@ Description: SqlListenerTests.verify_LoggingAsync, Status: Ok, IsSampled: true, - Extra: { + Data: { bytes_sent : 376, db.connection_id: Guid_2, db.name: SqlListenerTests.verify_LoggingAsync, @@ -49,7 +49,7 @@ VALUES (@p0); , Status: Ok, IsSampled: true, - Extra: { + Data: { db.connection_id: Guid_2, db.name: SqlListenerTests.verify_LoggingAsync, db.operation_id: Guid_4, diff --git a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.LoggingAsync.DotNet9_0.verified.txt b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.LoggingAsync.DotNet9_0.verified.txt index 298823718c..348b185b6f 100644 --- a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.LoggingAsync.DotNet9_0.verified.txt +++ b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.LoggingAsync.DotNet9_0.verified.txt @@ -27,7 +27,7 @@ Description: SqlListenerTests.verify_LoggingAsync, Status: Ok, IsSampled: true, - Extra: { + Data: { bytes_sent : 376, db.connection_id: Guid_2, db.name: SqlListenerTests.verify_LoggingAsync, @@ -49,7 +49,7 @@ VALUES (@p0); , Status: Ok, IsSampled: true, - Extra: { + Data: { db.connection_id: Guid_2, db.name: SqlListenerTests.verify_LoggingAsync, db.operation_id: Guid_4, diff --git a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.DotNet8_0.verified.txt b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.DotNet8_0.verified.txt index aa6dedca8c..58b52da963 100644 --- a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.DotNet8_0.verified.txt +++ b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.DotNet8_0.verified.txt @@ -61,7 +61,7 @@ Description: SqlListenerTests.verify_RecordsEfAsync, Status: Ok, IsSampled: true, - Extra: { + Data: { bytes_received: 225, bytes_sent : 570, db.connection_id: Guid_2, @@ -84,7 +84,7 @@ VALUES (@p0); , Status: Ok, IsSampled: true, - Extra: { + Data: { db.connection_id: Guid_2, db.name: SqlListenerTests.verify_RecordsEfAsync, db.operation_id: Guid_4, @@ -97,7 +97,7 @@ VALUES (@p0); Description: 'DbSet()', Status: Ok, IsSampled: true, - Extra: { + Data: { db.system: mssql } }, @@ -109,7 +109,7 @@ SELECT [t].[Id], [t].[Property] FROM [TestEntities] AS [t], Status: Ok, IsSampled: true, - Extra: { + Data: { db.connection_id: Guid_2, db.name: SqlListenerTests.verify_RecordsEfAsync, db.operation_id: Guid_5, diff --git a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.DotNet9_0.verified.txt b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.DotNet9_0.verified.txt index aa6dedca8c..58b52da963 100644 --- a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.DotNet9_0.verified.txt +++ b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.DotNet9_0.verified.txt @@ -61,7 +61,7 @@ Description: SqlListenerTests.verify_RecordsEfAsync, Status: Ok, IsSampled: true, - Extra: { + Data: { bytes_received: 225, bytes_sent : 570, db.connection_id: Guid_2, @@ -84,7 +84,7 @@ VALUES (@p0); , Status: Ok, IsSampled: true, - Extra: { + Data: { db.connection_id: Guid_2, db.name: SqlListenerTests.verify_RecordsEfAsync, db.operation_id: Guid_4, @@ -97,7 +97,7 @@ VALUES (@p0); Description: 'DbSet()', Status: Ok, IsSampled: true, - Extra: { + Data: { db.system: mssql } }, @@ -109,7 +109,7 @@ SELECT [t].[Id], [t].[Property] FROM [TestEntities] AS [t], Status: Ok, IsSampled: true, - Extra: { + Data: { db.connection_id: Guid_2, db.name: SqlListenerTests.verify_RecordsEfAsync, db.operation_id: Guid_5, diff --git a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.Net4_8.verified.txt b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.Net4_8.verified.txt index 96826b04ae..57227d296e 100644 --- a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.Net4_8.verified.txt +++ b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsEfAsync.Net4_8.verified.txt @@ -67,7 +67,7 @@ FROM [TestEntities] WHERE @@ROWCOUNT = 1 AND [Id] = scope_identity();, Status: Ok, IsSampled: true, - Extra: { + Data: { db.command_id: Guid_2, db.connection_id: Guid_3, db.name: SqlListenerTests.verify_RecordsEfAsync, @@ -83,7 +83,7 @@ SELECT [t].[Id], [t].[Property] FROM [TestEntities] AS [t], Status: Ok, IsSampled: true, - Extra: { + Data: { db.command_id: Guid_4, db.connection_id: Guid_5, db.name: SqlListenerTests.verify_RecordsEfAsync, diff --git a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsSqlAsync.verified.txt b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsSqlAsync.verified.txt index 7d7654f67d..0172e27d4e 100644 --- a/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsSqlAsync.verified.txt +++ b/test/Sentry.DiagnosticSource.IntegrationTests/SqlListenerTests.RecordsSqlAsync.verified.txt @@ -61,7 +61,7 @@ Description: SqlListenerTests.verify_RecordsSqlAsync, Status: Ok, IsSampled: true, - Extra: { + Data: { bytes_received: 167, bytes_sent : 536, db.connection_id: Guid_2, @@ -78,7 +78,7 @@ Description: insert into MyTable (Value) values (@value);, Status: Ok, IsSampled: true, - Extra: { + Data: { db.connection_id: Guid_2, db.name: SqlListenerTests.verify_RecordsSqlAsync, db.operation_id: Guid_4, @@ -91,7 +91,7 @@ Description: select Value from MyTable where Value = @value, Status: Ok, IsSampled: true, - Extra: { + Data: { db.connection_id: Guid_2, db.name: SqlListenerTests.verify_RecordsSqlAsync, db.operation_id: Guid_5, diff --git a/test/Sentry.Profiling.Tests/SamplingTransactionProfilerTests.cs b/test/Sentry.Profiling.Tests/SamplingTransactionProfilerTests.cs index 6f9ff84191..12bdcc5995 100644 --- a/test/Sentry.Profiling.Tests/SamplingTransactionProfilerTests.cs +++ b/test/Sentry.Profiling.Tests/SamplingTransactionProfilerTests.cs @@ -1,5 +1,4 @@ -using Microsoft.Diagnostics.Tracing; -using Microsoft.Diagnostics.Tracing.Parsers.Clr; +using System.IO.Abstractions.TestingHelpers; using Sentry.Internal.Http; namespace Sentry.Profiling.Tests; @@ -181,40 +180,6 @@ public async Task Profiler_AfterTimeout_Stops() } } - [SkippableFact] - public async Task EventPipeSession_ReceivesExpectedCLREvents() - { - Skip.If(TestEnvironment.IsGitHubActions, "Flaky on CI"); - - var session = SampleProfilerSession.StartNew(_testOutputLogger); - using (session) - { - var eventsReceived = new HashSet(); - session!.EventSource.Clr.All += (TraceEvent ev) => eventsReceived.Add(ev.EventName); - - var loadedMethods = new HashSet(); - session!.EventSource.Clr.MethodLoadVerbose += (MethodLoadUnloadVerboseTraceData ev) => loadedMethods.Add(ev.MethodName); - - await session.WaitForFirstEventAsync(CancellationToken.None); - var limitMs = 50; - var sut = new SamplingTransactionProfiler(_testSentryOptions, session, limitMs, CancellationToken.None); - RunForMs(limitMs * 5); - MethodToBeLoaded(100); - RunForMs(limitMs * 5); - sut.Finish(); - - Assert.Contains("Method/LoadVerbose", eventsReceived); - Assert.Contains("Method/ILToNativeMap", eventsReceived); - - Assert.Contains("MethodToBeLoaded", loadedMethods); - } - } - - private static long MethodToBeLoaded(int n) - { - return -n; - } - [SkippableTheory] [InlineData(true)] [InlineData(false)] diff --git a/test/Sentry.Profiling.Tests/TraceLogProcessorTests.ProfileInfo_Serialization_Works.verified.txt b/test/Sentry.Profiling.Tests/TraceLogProcessorTests.ProfileInfo_Serialization_Works.verified.txt index 481fcf2e42..714859c86d 100644 --- a/test/Sentry.Profiling.Tests/TraceLogProcessorTests.ProfileInfo_Serialization_Works.verified.txt +++ b/test/Sentry.Profiling.Tests/TraceLogProcessorTests.ProfileInfo_Serialization_Works.verified.txt @@ -107,12 +107,11 @@ 36 ], [ - 17 + 37 ], [ 0, 1, - 37, 38, 39, 40, @@ -120,37 +119,35 @@ 42, 43, 44, - 21, + 45, + 46, 22 ], [ - 45, - 46, 47, 48, 49, 50, - 17 - ], - [ 51, 52, + 37 + ], + [ 53, 54, 55, - 17 - ], - [ 56, 57, - 58, - 59, - 17 + 37 ], [ + 58, + 59, 60, 61, - 62, + 62 + ], + [ 63, 64, 65, @@ -158,55 +155,48 @@ 67, 68, 69, - 56, - 57, - 58, - 59, - 17 - ], - [ 70, 71, 72, - 73, - 74, - 69, - 56, - 57, 58, 59, - 17 + 60, + 61, + 62 ], [ - 75, + 73, 74, - 69, - 56, - 57, + 75, + 76, + 77, + 78, 58, 59, - 17 + 60, + 61, + 62 ], [ - 56, - 57, + 79, + 80, + 78, 58, 59, - 17 + 60, + 61, + 62 ], [ - 76, - 77, - 78, - 79, - 80, 81, - 82, - 83, 59, - 17 + 60, + 61, + 62 ], [ + 82, + 83, 84, 85, 86, @@ -214,22 +204,31 @@ 88, 89, 90, + 62 + ], + [ 91, 92, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 59, - 17 + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 62 ], [ 0, 1, - 37, 38, 39, 40, @@ -237,14 +236,15 @@ 42, 43, 44, - 21, + 45, + 46, 22 ], [ 18, 19, 20, - 21, + 101, 22 ] ], @@ -340,6 +340,7 @@ in_app: true }, { + in_app: false, instruction_addr: 0x7ff947fd8378 }, { @@ -432,6 +433,11 @@ module: System.Private.CoreLib.il, in_app: false }, + { + function: Aura.UI.Gallery.NetCore.Program.Main(class System.String[]), + module: Aura.UI.Gallery.NetCore, + in_app: true + }, { function: System.IO.Stream+<>c.b__40_0(class System.Object), module: System.Private.CoreLib.il, @@ -472,6 +478,11 @@ module: System.Private.CoreLib.il, in_app: false }, + { + function: System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart(), + module: System.Private.CoreLib.il, + in_app: false + }, { function: System.Collections.Concurrent.ConcurrentDictionary`2[System.__Canon,System.IntPtr].TryAddInternal(!0,value class System.Nullable`1,!1,bool,bool,!1&), module: System.Collections.Concurrent.il, @@ -498,6 +509,7 @@ in_app: true }, { + in_app: false, instruction_addr: 0x7ff94be7aed3 }, { @@ -545,6 +557,11 @@ module: Avalonia.Controls, in_app: true }, + { + function: Aura.UI.Gallery.NetCore.Program.Main(class System.String[]), + module: Aura.UI.Gallery.NetCore, + in_app: true + }, { function: Avalonia.Animation.Animation..cctor(), module: Avalonia.Animation, @@ -620,11 +637,26 @@ module: Avalonia.Controls, in_app: true }, + { + function: Avalonia.Controls.Primitives.TemplatedControl..cctor(), + module: Avalonia.Controls, + in_app: true + }, { function: System.Reactive.Linq.Observable.Merge(class System.IObservable`1[]), module: system.reactive, in_app: false }, + { + function: Avalonia.Controls.TextBlock..cctor(), + module: Avalonia.Controls, + in_app: true + }, + { + function: Avalonia.Controls.Window..cctor(), + module: Avalonia.Controls, + in_app: true + }, { function: Avalonia.Win32.Win32Platform.SetDpiAwareness(), module: avalonia.win32, @@ -665,6 +697,11 @@ module: Avalonia.Controls, in_app: true }, + { + function: Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(!!0,class System.String[],value class Avalonia.Controls.ShutdownMode), + module: Avalonia.Controls, + in_app: true + }, { function: System.Drawing.SafeNativeMethods+Gdip..cctor(), module: system.drawing.common, @@ -701,12 +738,23 @@ in_app: true }, { + in_app: false, instruction_addr: 0x7ffa0d468281 }, { function: Avalonia.Win32.Win32Platform.CreateMessageWindow(), module: avalonia.win32, in_app: true + }, + { + function: Avalonia.Win32.Win32Platform..ctor(), + module: avalonia.win32, + in_app: true + }, + { + function: System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart(), + module: System.Private.CoreLib.il, + in_app: false } ], samples: [ @@ -1022,4 +1070,4 @@ } ] } -} +} \ No newline at end of file diff --git a/test/Sentry.Profiling.Tests/TraceLogProcessorTests.Profile_Serialization_Works.verified.txt b/test/Sentry.Profiling.Tests/TraceLogProcessorTests.Profile_Serialization_Works.verified.txt index 7720ab6755..6eb35f3c22 100644 --- a/test/Sentry.Profiling.Tests/TraceLogProcessorTests.Profile_Serialization_Works.verified.txt +++ b/test/Sentry.Profiling.Tests/TraceLogProcessorTests.Profile_Serialization_Works.verified.txt @@ -84,12 +84,11 @@ 36 ], [ - 17 + 37 ], [ 0, 1, - 37, 38, 39, 40, @@ -97,37 +96,35 @@ 42, 43, 44, - 21, + 45, + 46, 22 ], [ - 45, - 46, 47, 48, 49, 50, - 17 - ], - [ 51, 52, + 37 + ], + [ 53, 54, 55, - 17 - ], - [ 56, 57, - 58, - 59, - 17 + 37 ], [ + 58, + 59, 60, 61, - 62, + 62 + ], + [ 63, 64, 65, @@ -135,55 +132,48 @@ 67, 68, 69, - 56, - 57, - 58, - 59, - 17 - ], - [ 70, 71, 72, - 73, - 74, - 69, - 56, - 57, 58, 59, - 17 + 60, + 61, + 62 ], [ - 75, + 73, 74, - 69, - 56, - 57, + 75, + 76, + 77, + 78, 58, 59, - 17 + 60, + 61, + 62 ], [ - 56, - 57, + 79, + 80, + 78, 58, 59, - 17 + 60, + 61, + 62 ], [ - 76, - 77, - 78, - 79, - 80, 81, - 82, - 83, 59, - 17 + 60, + 61, + 62 ], [ + 82, + 83, 84, 85, 86, @@ -191,22 +181,31 @@ 88, 89, 90, + 62 + ], + [ 91, 92, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 59, - 17 + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 62 ], [ 0, 1, - 37, 38, 39, 40, @@ -214,14 +213,15 @@ 42, 43, 44, - 21, + 45, + 46, 22 ], [ 18, 19, 20, - 21, + 101, 22 ] ], @@ -317,6 +317,7 @@ in_app: true }, { + in_app: false, instruction_addr: 0x7ff947fd8378 }, { @@ -409,6 +410,11 @@ module: System.Private.CoreLib.il, in_app: false }, + { + function: Aura.UI.Gallery.NetCore.Program.Main(class System.String[]), + module: Aura.UI.Gallery.NetCore, + in_app: true + }, { function: System.IO.Stream+<>c.b__40_0(class System.Object), module: System.Private.CoreLib.il, @@ -449,6 +455,11 @@ module: System.Private.CoreLib.il, in_app: false }, + { + function: System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart(), + module: System.Private.CoreLib.il, + in_app: false + }, { function: System.Collections.Concurrent.ConcurrentDictionary`2[System.__Canon,System.IntPtr].TryAddInternal(!0,value class System.Nullable`1,!1,bool,bool,!1&), module: System.Collections.Concurrent.il, @@ -475,6 +486,7 @@ in_app: true }, { + in_app: false, instruction_addr: 0x7ff94be7aed3 }, { @@ -522,6 +534,11 @@ module: Avalonia.Controls, in_app: true }, + { + function: Aura.UI.Gallery.NetCore.Program.Main(class System.String[]), + module: Aura.UI.Gallery.NetCore, + in_app: true + }, { function: Avalonia.Animation.Animation..cctor(), module: Avalonia.Animation, @@ -597,11 +614,26 @@ module: Avalonia.Controls, in_app: true }, + { + function: Avalonia.Controls.Primitives.TemplatedControl..cctor(), + module: Avalonia.Controls, + in_app: true + }, { function: System.Reactive.Linq.Observable.Merge(class System.IObservable`1[]), module: system.reactive, in_app: false }, + { + function: Avalonia.Controls.TextBlock..cctor(), + module: Avalonia.Controls, + in_app: true + }, + { + function: Avalonia.Controls.Window..cctor(), + module: Avalonia.Controls, + in_app: true + }, { function: Avalonia.Win32.Win32Platform.SetDpiAwareness(), module: avalonia.win32, @@ -642,6 +674,11 @@ module: Avalonia.Controls, in_app: true }, + { + function: Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(!!0,class System.String[],value class Avalonia.Controls.ShutdownMode), + module: Avalonia.Controls, + in_app: true + }, { function: System.Drawing.SafeNativeMethods+Gdip..cctor(), module: system.drawing.common, @@ -678,12 +715,23 @@ in_app: true }, { + in_app: false, instruction_addr: 0x7ffa0d468281 }, { function: Avalonia.Win32.Win32Platform.CreateMessageWindow(), module: avalonia.win32, in_app: true + }, + { + function: Avalonia.Win32.Win32Platform..ctor(), + module: avalonia.win32, + in_app: true + }, + { + function: System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart(), + module: System.Private.CoreLib.il, + in_app: false } ], samples: [ @@ -998,4 +1046,4 @@ stack_id: 18 } ] -} +} \ No newline at end of file diff --git a/test/Sentry.Profiling.Tests/TraceLogProcessorTests.verify.cs b/test/Sentry.Profiling.Tests/TraceLogProcessorTests.verify.cs index 7a01150aec..5b4307e951 100644 --- a/test/Sentry.Profiling.Tests/TraceLogProcessorTests.verify.cs +++ b/test/Sentry.Profiling.Tests/TraceLogProcessorTests.verify.cs @@ -20,24 +20,16 @@ public TraceLogProcessorTests(ITestOutputHelper output) // [Fact] // public void ManualDebugging() // { - // var etlFilePath = "T:/src/sentry-dotnet/samples/Sentry.Samples.Console.Profiling/Sentry.Samples.Console.Profiling.exe_20250124_144756.nettrace"; + // var etlFilePath = "C:/dev/Aura.UI/profile.nettrace"; // var etlxFilePath = Path.ChangeExtension(etlFilePath, ".etlx"); // if (!File.Exists(etlxFilePath)) // { // TraceLog.CreateFromEventTraceLogFile(etlFilePath, etlxFilePath); // } // using var eventLog = new TraceLog(etlxFilePath); - // var builder = new SampleProfileBuilder(new(), eventLog); - // foreach (var event_ in eventLog.Events) - // { - // if (event_.ProviderGuid == SampleProfilerTraceEventParser.ProviderGuid) - // { - // builder.AddSample(event_, event_.TimeStampRelativeMSec); - // } - // } - - // var json = builder.Profile.ToJsonString(_testOutputLogger); - // VerifyJson(json); + // var processor = new TraceLogProcessor(new(), eventLog); + // var profile = processor.Process(CancellationToken.None); + // var json = profile.ToJsonString(_testOutputLogger); // } private SampleProfile BuilProfile(TraceLogEventSource eventSource) diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt index 843b28f7e4..2a4a0e61a3 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt @@ -190,6 +190,11 @@ namespace Sentry Sentry.SentryUser User { get; set; } void AddBreadcrumb(Sentry.Breadcrumb breadcrumb); } + public interface IHasData + { + System.Collections.Generic.IReadOnlyDictionary Data { get; } + void SetData(string key, object? value); + } public interface IHasExtra { System.Collections.Generic.IReadOnlyDictionary Extra { get; } @@ -269,7 +274,7 @@ namespace Sentry { Sentry.SentryUser? Create(); } - public interface ISpan : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public interface ISpan : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.Protocol.ITraceContext { new string? Description { get; set; } new string Operation { get; set; } @@ -280,7 +285,7 @@ namespace Sentry void Finish(System.Exception exception, Sentry.SpanStatus status); Sentry.ISpan StartChild(string operation); } - public interface ISpanData : Sentry.IHasExtra, Sentry.IHasTags, Sentry.Protocol.ITraceContext + public interface ISpanData : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.Protocol.ITraceContext { System.DateTimeOffset? EndTimestamp { get; } bool IsFinished { get; } @@ -295,11 +300,11 @@ namespace Sentry string Name { get; } Sentry.TransactionNameSource NameSource { get; } } - public interface ITransactionData : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.Protocol.ITraceContext + public interface ITransactionData : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.Protocol.ITraceContext { string? Platform { get; set; } } - public interface ITransactionTracer : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext + public interface ITransactionTracer : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext { new bool? IsParentSampled { get; set; } new string Name { get; set; } @@ -849,12 +854,14 @@ namespace Sentry public string? UserAgent { get; } public void ReportError() { } } - public class SentrySpan : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public class SentrySpan : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.Protocol.ITraceContext { public SentrySpan(Sentry.ISpan tracer) { } public SentrySpan(Sentry.SpanId? parentSpanId, string operation) { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public System.DateTimeOffset? EndTimestamp { get; } + [System.Obsolete("Use SetData")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public bool IsFinished { get; } public bool? IsSampled { get; } @@ -868,6 +875,8 @@ namespace Sentry public System.Collections.Generic.IReadOnlyDictionary Tags { get; } public Sentry.SentryId TraceId { get; } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use Data")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -930,18 +939,20 @@ namespace Sentry public override string ToString() { } public static Sentry.SentryTraceHeader? Parse(string value) { } } - public class SentryTransaction : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext + public class SentryTransaction : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext { public SentryTransaction(Sentry.ITransactionTracer tracer) { } public SentryTransaction(string name, string operation) { } public SentryTransaction(string name, string operation, Sentry.TransactionNameSource nameSource) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public string? Distribution { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } + [System.Obsolete("Use Data")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public bool IsFinished { get; } @@ -968,6 +979,8 @@ namespace Sentry public Sentry.SentryUser User { get; set; } public void AddBreadcrumb(Sentry.Breadcrumb breadcrumb) { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use SetData")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1078,9 +1091,10 @@ namespace Sentry OutOfRange = 15, DataLoss = 16, } - public class SpanTracer : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public class SpanTracer : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.Protocol.ITraceContext { public SpanTracer(Sentry.IHub hub, Sentry.TransactionTracer transaction, Sentry.SpanId? parentSpanId, Sentry.SentryId traceId, string operation) { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public System.Collections.Generic.IReadOnlyDictionary Extra { get; } @@ -1100,6 +1114,7 @@ namespace Sentry public void Finish(System.Exception exception) { } public void Finish(System.Exception exception, Sentry.SpanStatus status) { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1155,15 +1170,17 @@ namespace Sentry public System.Collections.Generic.IReadOnlyDictionary CustomSamplingContext { get; } public Sentry.ITransactionContext TransactionContext { get; } } - public class TransactionTracer : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.ITransactionTracer, Sentry.Protocol.ITraceContext + public class TransactionTracer : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.ITransactionTracer, Sentry.Protocol.ITraceContext { public TransactionTracer(Sentry.IHub hub, Sentry.ITransactionContext context) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public string? Distribution { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public string? Environment { get; set; } + [System.Obsolete("Use Data")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public bool IsFinished { get; } @@ -1195,6 +1212,8 @@ namespace Sentry public void Finish(System.Exception exception, Sentry.SpanStatus status) { } public Sentry.ISpan? GetLastActiveSpan() { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use SetData")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1749,6 +1768,7 @@ namespace Sentry.Protocol { public const string Type = "trace"; public Trace() { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public bool? IsSampled { get; } public string Operation { get; set; } @@ -1757,6 +1777,7 @@ namespace Sentry.Protocol public Sentry.SpanId SpanId { get; set; } public Sentry.SpanStatus? Status { get; set; } public Sentry.SentryId TraceId { get; set; } + public void SetData(string key, object? value) { } public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Protocol.Trace FromJson(System.Text.Json.JsonElement json) { } } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt index 843b28f7e4..2a4a0e61a3 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt @@ -190,6 +190,11 @@ namespace Sentry Sentry.SentryUser User { get; set; } void AddBreadcrumb(Sentry.Breadcrumb breadcrumb); } + public interface IHasData + { + System.Collections.Generic.IReadOnlyDictionary Data { get; } + void SetData(string key, object? value); + } public interface IHasExtra { System.Collections.Generic.IReadOnlyDictionary Extra { get; } @@ -269,7 +274,7 @@ namespace Sentry { Sentry.SentryUser? Create(); } - public interface ISpan : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public interface ISpan : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.Protocol.ITraceContext { new string? Description { get; set; } new string Operation { get; set; } @@ -280,7 +285,7 @@ namespace Sentry void Finish(System.Exception exception, Sentry.SpanStatus status); Sentry.ISpan StartChild(string operation); } - public interface ISpanData : Sentry.IHasExtra, Sentry.IHasTags, Sentry.Protocol.ITraceContext + public interface ISpanData : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.Protocol.ITraceContext { System.DateTimeOffset? EndTimestamp { get; } bool IsFinished { get; } @@ -295,11 +300,11 @@ namespace Sentry string Name { get; } Sentry.TransactionNameSource NameSource { get; } } - public interface ITransactionData : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.Protocol.ITraceContext + public interface ITransactionData : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.Protocol.ITraceContext { string? Platform { get; set; } } - public interface ITransactionTracer : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext + public interface ITransactionTracer : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext { new bool? IsParentSampled { get; set; } new string Name { get; set; } @@ -849,12 +854,14 @@ namespace Sentry public string? UserAgent { get; } public void ReportError() { } } - public class SentrySpan : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public class SentrySpan : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.Protocol.ITraceContext { public SentrySpan(Sentry.ISpan tracer) { } public SentrySpan(Sentry.SpanId? parentSpanId, string operation) { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public System.DateTimeOffset? EndTimestamp { get; } + [System.Obsolete("Use SetData")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public bool IsFinished { get; } public bool? IsSampled { get; } @@ -868,6 +875,8 @@ namespace Sentry public System.Collections.Generic.IReadOnlyDictionary Tags { get; } public Sentry.SentryId TraceId { get; } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use Data")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -930,18 +939,20 @@ namespace Sentry public override string ToString() { } public static Sentry.SentryTraceHeader? Parse(string value) { } } - public class SentryTransaction : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext + public class SentryTransaction : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext { public SentryTransaction(Sentry.ITransactionTracer tracer) { } public SentryTransaction(string name, string operation) { } public SentryTransaction(string name, string operation, Sentry.TransactionNameSource nameSource) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public string? Distribution { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } + [System.Obsolete("Use Data")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public bool IsFinished { get; } @@ -968,6 +979,8 @@ namespace Sentry public Sentry.SentryUser User { get; set; } public void AddBreadcrumb(Sentry.Breadcrumb breadcrumb) { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use SetData")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1078,9 +1091,10 @@ namespace Sentry OutOfRange = 15, DataLoss = 16, } - public class SpanTracer : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public class SpanTracer : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.Protocol.ITraceContext { public SpanTracer(Sentry.IHub hub, Sentry.TransactionTracer transaction, Sentry.SpanId? parentSpanId, Sentry.SentryId traceId, string operation) { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public System.Collections.Generic.IReadOnlyDictionary Extra { get; } @@ -1100,6 +1114,7 @@ namespace Sentry public void Finish(System.Exception exception) { } public void Finish(System.Exception exception, Sentry.SpanStatus status) { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1155,15 +1170,17 @@ namespace Sentry public System.Collections.Generic.IReadOnlyDictionary CustomSamplingContext { get; } public Sentry.ITransactionContext TransactionContext { get; } } - public class TransactionTracer : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.ITransactionTracer, Sentry.Protocol.ITraceContext + public class TransactionTracer : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.ITransactionTracer, Sentry.Protocol.ITraceContext { public TransactionTracer(Sentry.IHub hub, Sentry.ITransactionContext context) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public string? Distribution { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public string? Environment { get; set; } + [System.Obsolete("Use Data")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public bool IsFinished { get; } @@ -1195,6 +1212,8 @@ namespace Sentry public void Finish(System.Exception exception, Sentry.SpanStatus status) { } public Sentry.ISpan? GetLastActiveSpan() { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use SetData")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1749,6 +1768,7 @@ namespace Sentry.Protocol { public const string Type = "trace"; public Trace() { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public bool? IsSampled { get; } public string Operation { get; set; } @@ -1757,6 +1777,7 @@ namespace Sentry.Protocol public Sentry.SpanId SpanId { get; set; } public Sentry.SpanStatus? Status { get; set; } public Sentry.SentryId TraceId { get; set; } + public void SetData(string key, object? value) { } public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Protocol.Trace FromJson(System.Text.Json.JsonElement json) { } } diff --git a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt index a14cf232b7..2730a34f6d 100644 --- a/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt +++ b/test/Sentry.Tests/ApiApprovalTests.Run.Net4_8.verified.txt @@ -178,6 +178,11 @@ namespace Sentry Sentry.SentryUser User { get; set; } void AddBreadcrumb(Sentry.Breadcrumb breadcrumb); } + public interface IHasData + { + System.Collections.Generic.IReadOnlyDictionary Data { get; } + void SetData(string key, object? value); + } public interface IHasExtra { System.Collections.Generic.IReadOnlyDictionary Extra { get; } @@ -257,7 +262,7 @@ namespace Sentry { Sentry.SentryUser? Create(); } - public interface ISpan : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public interface ISpan : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.Protocol.ITraceContext { new string? Description { get; set; } new string Operation { get; set; } @@ -268,7 +273,7 @@ namespace Sentry void Finish(System.Exception exception, Sentry.SpanStatus status); Sentry.ISpan StartChild(string operation); } - public interface ISpanData : Sentry.IHasExtra, Sentry.IHasTags, Sentry.Protocol.ITraceContext + public interface ISpanData : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.Protocol.ITraceContext { System.DateTimeOffset? EndTimestamp { get; } bool IsFinished { get; } @@ -283,11 +288,11 @@ namespace Sentry string Name { get; } Sentry.TransactionNameSource NameSource { get; } } - public interface ITransactionData : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.Protocol.ITraceContext + public interface ITransactionData : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.Protocol.ITraceContext { string? Platform { get; set; } } - public interface ITransactionTracer : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext + public interface ITransactionTracer : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext { new bool? IsParentSampled { get; set; } new string Name { get; set; } @@ -830,12 +835,14 @@ namespace Sentry public string? UserAgent { get; } public void ReportError() { } } - public class SentrySpan : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public class SentrySpan : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.Protocol.ITraceContext { public SentrySpan(Sentry.ISpan tracer) { } public SentrySpan(Sentry.SpanId? parentSpanId, string operation) { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public System.DateTimeOffset? EndTimestamp { get; } + [System.Obsolete("Use SetData")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public bool IsFinished { get; } public bool? IsSampled { get; } @@ -849,6 +856,8 @@ namespace Sentry public System.Collections.Generic.IReadOnlyDictionary Tags { get; } public Sentry.SentryId TraceId { get; } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use Data")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -911,18 +920,20 @@ namespace Sentry public override string ToString() { } public static Sentry.SentryTraceHeader? Parse(string value) { } } - public class SentryTransaction : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext + public class SentryTransaction : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISentryJsonSerializable, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.Protocol.ITraceContext { public SentryTransaction(Sentry.ITransactionTracer tracer) { } public SentryTransaction(string name, string operation) { } public SentryTransaction(string name, string operation, Sentry.TransactionNameSource nameSource) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public string? Distribution { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public string? Environment { get; set; } public Sentry.SentryId EventId { get; } + [System.Obsolete("Use Data")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public bool IsFinished { get; } @@ -949,6 +960,8 @@ namespace Sentry public Sentry.SentryUser User { get; set; } public void AddBreadcrumb(Sentry.Breadcrumb breadcrumb) { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use SetData")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1059,9 +1072,10 @@ namespace Sentry OutOfRange = 15, DataLoss = 16, } - public class SpanTracer : Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.Protocol.ITraceContext + public class SpanTracer : Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.Protocol.ITraceContext { public SpanTracer(Sentry.IHub hub, Sentry.TransactionTracer transaction, Sentry.SpanId? parentSpanId, Sentry.SentryId traceId, string operation) { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public System.Collections.Generic.IReadOnlyDictionary Extra { get; } @@ -1081,6 +1095,7 @@ namespace Sentry public void Finish(System.Exception exception) { } public void Finish(System.Exception exception, Sentry.SpanStatus status) { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1136,15 +1151,17 @@ namespace Sentry public System.Collections.Generic.IReadOnlyDictionary CustomSamplingContext { get; } public Sentry.ITransactionContext TransactionContext { get; } } - public class TransactionTracer : Sentry.IEventLike, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.ITransactionTracer, Sentry.Protocol.ITraceContext + public class TransactionTracer : Sentry.IEventLike, Sentry.IHasData, Sentry.IHasExtra, Sentry.IHasTags, Sentry.ISpan, Sentry.ISpanData, Sentry.ITransactionContext, Sentry.ITransactionData, Sentry.ITransactionTracer, Sentry.Protocol.ITraceContext { public TransactionTracer(Sentry.IHub hub, Sentry.ITransactionContext context) { } public System.Collections.Generic.IReadOnlyCollection Breadcrumbs { get; } public Sentry.SentryContexts Contexts { get; set; } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public string? Distribution { get; set; } public System.DateTimeOffset? EndTimestamp { get; } public string? Environment { get; set; } + [System.Obsolete("Use Data")] public System.Collections.Generic.IReadOnlyDictionary Extra { get; } public System.Collections.Generic.IReadOnlyList Fingerprint { get; set; } public bool IsFinished { get; } @@ -1176,6 +1193,8 @@ namespace Sentry public void Finish(System.Exception exception, Sentry.SpanStatus status) { } public Sentry.ISpan? GetLastActiveSpan() { } public Sentry.SentryTraceHeader GetTraceHeader() { } + public void SetData(string key, object? value) { } + [System.Obsolete("Use SetData")] public void SetExtra(string key, object? value) { } public void SetMeasurement(string name, Sentry.Protocol.Measurement measurement) { } public void SetTag(string key, string value) { } @@ -1731,6 +1750,7 @@ namespace Sentry.Protocol { public const string Type = "trace"; public Trace() { } + public System.Collections.Generic.IReadOnlyDictionary Data { get; } public string? Description { get; set; } public bool? IsSampled { get; } public string Operation { get; set; } @@ -1739,6 +1759,7 @@ namespace Sentry.Protocol public Sentry.SpanId SpanId { get; set; } public Sentry.SpanStatus? Status { get; set; } public Sentry.SentryId TraceId { get; set; } + public void SetData(string key, object? value) { } public void WriteTo(System.Text.Json.Utf8JsonWriter writer, Sentry.Extensibility.IDiagnosticLogger? logger) { } public static Sentry.Protocol.Trace FromJson(System.Text.Json.JsonElement json) { } }