Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Metrics Support - alpha #2949

Merged
merged 60 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from 57 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
5794a6c
Added basic metric types
jamescrosswell Dec 4, 2023
3752fd5
Moved Metric classes
jamescrosswell Dec 5, 2023
0d6587b
Added Increment aggregator
jamescrosswell Dec 6, 2023
088e4fd
Implemented Gauge metric
jamescrosswell Dec 6, 2023
9fac649
Implemented Distribution and Set aggregations
jamescrosswell Dec 6, 2023
c65355d
Added Metrics to ISentryClient API
jamescrosswell Dec 6, 2023
b77c04d
Update Hub.cs
jamescrosswell Dec 6, 2023
c0233db
Verify tests
jamescrosswell Dec 6, 2023
3b74b80
Basic flush loop (no tests yet)
jamescrosswell Dec 6, 2023
c83e9c9
Implemented statsd serialization
jamescrosswell Dec 7, 2023
9150098
Update CHANGELOG.md
jamescrosswell Dec 7, 2023
19dc74a
Split tests for Aggregagtor and BucketHelper
jamescrosswell Dec 7, 2023
cac0d79
Update MetricBucketHelperTests.cs
jamescrosswell Dec 7, 2023
721e6b3
Integrated review feedback
jamescrosswell Dec 10, 2023
a7ba47e
Create MetricTests.verify.cs
jamescrosswell Dec 11, 2023
90be220
Updated verify tests
jamescrosswell Dec 11, 2023
73be790
Merge branch 'main' into metrics
jamescrosswell Dec 11, 2023
94790d7
Added Timing
jamescrosswell Dec 11, 2023
e05f8ee
Merge branch 'metrics' of github.com:getsentry/sentry-dotnet into met…
jamescrosswell Dec 11, 2023
54af5c2
Added a (commented out) test to check if the aggregator is threadsafe
jamescrosswell Dec 11, 2023
9344f38
Fixed concurrency issue (could still make this more performant)
jamescrosswell Dec 12, 2023
5827608
Reduced the scope of the lock for updating metrics
jamescrosswell Dec 12, 2023
f3275ac
Fixed unit tests
jamescrosswell Dec 12, 2023
0f86158
Update MetricAggregator.cs
jamescrosswell Dec 12, 2023
7a75155
Initial implementation of Code Locations
jamescrosswell Dec 14, 2023
a116f56
Merge branch 'main' into metrics
jamescrosswell Dec 14, 2023
7f47f1a
Update Program.cs
jamescrosswell Dec 14, 2023
cd83a4e
Updated solution filters
jamescrosswell Dec 14, 2023
826a413
Update CHANGELOG.md
jamescrosswell Dec 14, 2023
994b8ba
Changed Flush to FlushAsync
jamescrosswell Dec 14, 2023
8e7f0ce
Metrics now get flushed properly when disposing of the Hub
jamescrosswell Dec 14, 2023
aa3682f
Fixed serialization for code locations
jamescrosswell Dec 14, 2023
d9918d8
Update Timing.cs
jamescrosswell Dec 14, 2023
6de5909
Clear stale seen periods at the end of each day
jamescrosswell Dec 15, 2023
d180a9d
Update CodeLocations.cs
jamescrosswell Dec 15, 2023
2a6f344
Fixed stacklevel when calling one of the two Timing constructors
jamescrosswell Dec 15, 2023
052c7a9
Removed IAsyncDisposable from MetricAggregator
jamescrosswell Dec 18, 2023
82469ba
Merge branch 'main' into metrics
jamescrosswell Dec 18, 2023
2eedd9c
Cherry picked https://github.com/getsentry/Ben.Demystifier/pull/4
jamescrosswell Dec 18, 2023
18a08bd
Merge branch 'metrics' of github.com:getsentry/sentry-dotnet into met…
jamescrosswell Dec 18, 2023
c72c7e1
Update Ben.Demystifier
jamescrosswell Dec 18, 2023
2a323c5
Get line numbers with stack traces without enhanced stack traces
jamescrosswell Dec 19, 2023
57e2b12
Update Ben.Demystifier
jamescrosswell Dec 19, 2023
d2c6cb5
Reversed changes to AspNetCore.Basic sample (unrelated to this PR)
jamescrosswell Dec 19, 2023
a9c5d6b
Update Program.cs
jamescrosswell Dec 19, 2023
30ef3b4
Improved the lock when incrementing/adding to existing metrics
jamescrosswell Dec 19, 2023
34a5c3e
Tweaking docs
jamescrosswell Dec 19, 2023
7faa57c
Update CHANGELOG.md
jamescrosswell Dec 20, 2023
d956b5d
Integrating review feedback
jamescrosswell Dec 20, 2023
3efab8a
Source generated RegEx in metric helper
jamescrosswell Dec 20, 2023
62a7001
Merge branch 'metrics' of github.com:getsentry/sentry-dotnet into met…
jamescrosswell Dec 20, 2023
c68c25c
Update Envelope.cs
jamescrosswell Dec 20, 2023
1c3b275
Merge branch 'main' into metrics
jamescrosswell Dec 21, 2023
4cb9ef7
Review feedback
jamescrosswell Dec 27, 2023
36fe029
Merge branch 'main' into metrics
jamescrosswell Dec 27, 2023
8cc439c
Integrating review feedback
jamescrosswell Jan 3, 2024
705d131
More performant string delimited tags used in the bucket key
jamescrosswell Jan 4, 2024
353a928
Integrating review feedback
jamescrosswell Jan 4, 2024
589c3b2
Integrated review feedback
jamescrosswell Jan 6, 2024
bce6e50
Removed unused private field
jamescrosswell Jan 6, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Features

- Experimental pre-release availability of Metrics. We're exploring the use of Metrics in Sentry. The API will very likely change and we don't yet have any documentation. ([#2949](https://github.com/getsentry/sentry-dotnet/pull/2949))
- MAUI Screenshot support. You can opt-in via `SentryMauiOptions.AttachScreenshots` ([#2965](https://github.com/getsentry/sentry-dotnet/pull/2965))
- Supports Android and iOS only. Windows is not supported.
- MAUI: App context has `in_foreground` indicating whether app was on the background or foreground. ([#2983](https://github.com/getsentry/sentry-dotnet/pull/2983))
Expand Down
1 change: 1 addition & 0 deletions Sentry-CI-Build-Linux.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"samples\\Sentry.Samples.Azure.Functions.Worker\\Sentry.Samples.Azure.Functions.Worker.csproj",
"samples\\Sentry.Samples.Console.Basic\\Sentry.Samples.Console.Basic.csproj",
"samples\\Sentry.Samples.Console.Customized\\Sentry.Samples.Console.Customized.csproj",
"samples\\Sentry.Samples.Console.Metrics\\Sentry.Samples.Console.Metrics.csproj",
"samples\\Sentry.Samples.Console.Native\\Sentry.Samples.Console.Native.csproj",
"samples\\Sentry.Samples.Console.Profiling\\Sentry.Samples.Console.Profiling.csproj",
"samples\\Sentry.Samples.EntityFramework\\Sentry.Samples.EntityFramework.csproj",
Expand Down
1 change: 1 addition & 0 deletions Sentry-CI-Build-Windows.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"samples\\Sentry.Samples.Azure.Functions.Worker\\Sentry.Samples.Azure.Functions.Worker.csproj",
"samples\\Sentry.Samples.Console.Basic\\Sentry.Samples.Console.Basic.csproj",
"samples\\Sentry.Samples.Console.Customized\\Sentry.Samples.Console.Customized.csproj",
"samples\\Sentry.Samples.Console.Metrics\\Sentry.Samples.Console.Metrics.csproj",
"samples\\Sentry.Samples.Console.Native\\Sentry.Samples.Console.Native.csproj",
"samples\\Sentry.Samples.Console.Profiling\\Sentry.Samples.Console.Profiling.csproj",
"samples\\Sentry.Samples.EntityFramework\\Sentry.Samples.EntityFramework.csproj",
Expand Down
1 change: 1 addition & 0 deletions Sentry-CI-Build-macOS.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"samples\\Sentry.Samples.Azure.Functions.Worker\\Sentry.Samples.Azure.Functions.Worker.csproj",
"samples\\Sentry.Samples.Console.Basic\\Sentry.Samples.Console.Basic.csproj",
"samples\\Sentry.Samples.Console.Customized\\Sentry.Samples.Console.Customized.csproj",
"samples\\Sentry.Samples.Console.Metrics\\Sentry.Samples.Console.Metrics.csproj",
"samples\\Sentry.Samples.Console.Native\\Sentry.Samples.Console.Native.csproj",
"samples\\Sentry.Samples.Console.Profiling\\Sentry.Samples.Console.Profiling.csproj",
"samples\\Sentry.Samples.EntityFramework\\Sentry.Samples.EntityFramework.csproj",
Expand Down
7 changes: 7 additions & 0 deletions Sentry.NoMobile.sln
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastSerialization", "module
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.Samples.Console.Native", "samples\Sentry.Samples.Console.Native\Sentry.Samples.Console.Native.csproj", "{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.Samples.Console.Metrics", "samples\Sentry.Samples.Console.Metrics\Sentry.Samples.Console.Metrics.csproj", "{BD2D08FC-8675-4157-A73C-D75F6A3856D3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -465,6 +467,10 @@ Global
{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2}.Release|Any CPU.Build.0 = Release|Any CPU
{BD2D08FC-8675-4157-A73C-D75F6A3856D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD2D08FC-8675-4157-A73C-D75F6A3856D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD2D08FC-8675-4157-A73C-D75F6A3856D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD2D08FC-8675-4157-A73C-D75F6A3856D3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -545,5 +551,6 @@ Global
{67269916-C417-4CEE-BD7D-CA66C3830AEE} = {A3CCA27E-4DF8-479D-833C-CAA0950715AA}
{8032310D-3C06-442C-A318-F365BCC4C804} = {A3CCA27E-4DF8-479D-833C-CAA0950715AA}
{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2} = {21B42F60-5802-404E-90F0-AEBCC56760C0}
{BD2D08FC-8675-4157-A73C-D75F6A3856D3} = {21B42F60-5802-404E-90F0-AEBCC56760C0}
EndGlobalSection
EndGlobal
7 changes: 7 additions & 0 deletions Sentry.sln
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastSerialization", "module
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.Samples.Console.Native", "samples\Sentry.Samples.Console.Native\Sentry.Samples.Console.Native.csproj", "{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sentry.Samples.Console.Metrics", "samples\Sentry.Samples.Console.Metrics\Sentry.Samples.Console.Metrics.csproj", "{BD2D08FC-8675-4157-A73C-D75F6A3856D3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -465,6 +467,10 @@ Global
{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2}.Release|Any CPU.Build.0 = Release|Any CPU
{BD2D08FC-8675-4157-A73C-D75F6A3856D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BD2D08FC-8675-4157-A73C-D75F6A3856D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BD2D08FC-8675-4157-A73C-D75F6A3856D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BD2D08FC-8675-4157-A73C-D75F6A3856D3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -545,5 +551,6 @@ Global
{67269916-C417-4CEE-BD7D-CA66C3830AEE} = {A3CCA27E-4DF8-479D-833C-CAA0950715AA}
{8032310D-3C06-442C-A318-F365BCC4C804} = {A3CCA27E-4DF8-479D-833C-CAA0950715AA}
{FC8AEABA-1A40-4891-9EBA-4B6A1F7244B2} = {21B42F60-5802-404E-90F0-AEBCC56760C0}
{BD2D08FC-8675-4157-A73C-D75F6A3856D3} = {21B42F60-5802-404E-90F0-AEBCC56760C0}
EndGlobalSection
EndGlobal
1 change: 1 addition & 0 deletions SentryNoMobile.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"samples\\Sentry.Samples.Azure.Functions.Worker\\Sentry.Samples.Azure.Functions.Worker.csproj",
"samples\\Sentry.Samples.Console.Basic\\Sentry.Samples.Console.Basic.csproj",
"samples\\Sentry.Samples.Console.Customized\\Sentry.Samples.Console.Customized.csproj",
"samples\\Sentry.Samples.Console.Metrics\\Sentry.Samples.Console.Metrics.csproj",
"samples\\Sentry.Samples.Console.Native\\Sentry.Samples.Console.Native.csproj",
"samples\\Sentry.Samples.Console.Profiling\\Sentry.Samples.Console.Profiling.csproj",
"samples\\Sentry.Samples.EntityFramework\\Sentry.Samples.EntityFramework.csproj",
Expand Down
2 changes: 1 addition & 1 deletion modules/Ben.Demystifier
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

110 changes: 110 additions & 0 deletions samples/Sentry.Samples.Console.Metrics/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System.Numerics;

namespace Sentry.Samples.Console.Metrics;

internal static class Program
{
private static readonly Random Roll = new();

private static void Main()
{
// Enable the SDK
using (SentrySdk.Init(options =>
{
options.Dsn =
// NOTE: ADD YOUR OWN DSN BELOW so you can see the events in your own Sentry account
"https://[email protected]/5428537";

options.Debug = true;
options.StackTraceMode = StackTraceMode.Enhanced;
// Initialize some (non null) ExperimentalMetricsOptions to enable Sentry Metrics,
options.ExperimentalMetrics = new ExperimentalMetricsOptions
{
EnableCodeLocations =
true // Set this to false if you don't want to track code locations for some reason
};
}))
{
System.Console.WriteLine("Measure, Yeah, Measure!");
while (true)
{
// Perform your task here
switch (Roll.Next(1,3))
{
case 1:
PlaySetBingo(10);
break;
case 2:
CreateRevenueGauge(100);
break;
case 3:
MeasureShrimp(30);
break;
}


// Optional: Delay to prevent tight looping
var sleepTime = Roll.Next(1, 10);
System.Console.WriteLine($"Sleeping for {sleepTime} second(s).");
System.Console.WriteLine("Press any key to stop...");
Thread.Sleep(TimeSpan.FromSeconds(sleepTime));
// Check if a key has been pressed
if (System.Console.KeyAvailable)
{
break;
}
}
System.Console.WriteLine("Measure up");
}
}

private static void PlaySetBingo(int attempts)
{
var solution = new[] { 3, 5, 7, 11, 13, 17 };

// The Timing class creates a distribution that is designed to measure the amount of time it takes to run code
// blocks. By default it will use a unit of Seconds - we're configuring it to use milliseconds here though.
using (new Timing("bingo", MeasurementUnit.Duration.Millisecond))
{
for (var i = 0; i < attempts; i++)
{
var guess = Roll.Next(1, 100);
// This demonstrates the use of a set metric.
SentrySdk.Metrics.Gauge("guesses", guess);

if (solution.Contains(guess))
{
// And this is a counter
SentrySdk.Metrics.Increment("correct_answers");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this help us make sure correct+incorrect add up to guesses?

Suggested change
}
}
else
{
SentrySdk.Metrics.Increment("incorrect_answers");
}

}
}
}

private static void CreateRevenueGauge(int sampleCount)
{
using (new Timing(nameof(CreateRevenueGauge), MeasurementUnit.Duration.Millisecond))
{
for (var i = 0; i < sampleCount; i++)
{
var movement = Roll.NextDouble() * 30 - Roll.NextDouble() * 10;
// This demonstrates measuring something in your app using a gauge... we're also using a custom
// measurement unit here (which is optional - by default the unit will be "None")
SentrySdk.Metrics.Gauge("revenue", movement, MeasurementUnit.Custom("$"));
}
}
}

private static void MeasureShrimp(int sampleCount)
{
using (new Timing(nameof(MeasureShrimp), MeasurementUnit.Duration.Millisecond))
{
for (var i = 0; i < sampleCount; i++)
{
var sizeOfShrimp = 15 + Roll.NextDouble() * 30;
// This is an example of emitting a distribution metric
SentrySdk.Metrics.Distribution("shrimp.size", sizeOfShrimp, MeasurementUnit.Custom("cm"));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Sentry\Sentry.csproj" />
</ItemGroup>

</Project>
50 changes: 50 additions & 0 deletions src/Sentry/DisabledMetricAggregator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
namespace Sentry;

internal class DisabledMetricAggregator : IMetricAggregator
{
public void Increment(string key, double value = 1.0, MeasurementUnit? unit = null,
IDictionary<string, string>? tags = null,
DateTimeOffset? timestamp = null, int stackLevel = 1)
{
// No Op
}

public void Gauge(string key, double value = 1.0, MeasurementUnit? unit = null,
IDictionary<string, string>? tags = null,
DateTimeOffset? timestamp = null, int stackLevel = 1)
{
// No Op
}

public void Distribution(string key, double value = 1.0, MeasurementUnit? unit = null,
IDictionary<string, string>? tags = null,
DateTimeOffset? timestamp = null, int stackLevel = 1)
{
// No Op
}

public void Set(string key, double value = 1.0, MeasurementUnit? unit = null,
IDictionary<string, string>? tags = null,
DateTimeOffset? timestamp = null, int stackLevel = 1)
{
// No Op
}

public void Timing(string key, double value, MeasurementUnit.Duration unit = MeasurementUnit.Duration.Second,
IDictionary<string, string>? tags = null,
DateTimeOffset? timestamp = null, int stackLevel = 1)
{
// No Op
}

public Task FlushAsync(bool force = true, CancellationToken cancellationToken = default)
{
// No Op
return Task.CompletedTask;
}

public void Dispose()
{
// No Op
}
}
5 changes: 5 additions & 0 deletions src/Sentry/Extensibility/DisabledHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ public void CaptureSession(SessionUpdate sessionUpdate)
/// </summary>
public Task FlushAsync(TimeSpan timeout) => Task.CompletedTask;

/// <summary>
/// Disabled Metrics Aggregator (all methods are no-op).
/// </summary>
public IMetricAggregator Metrics { get; } = new DisabledMetricAggregator();

/// <summary>
/// No-Op.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions src/Sentry/Extensibility/HubAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,10 @@ public void CaptureSession(SessionUpdate sessionUpdate)
public Task FlushAsync(TimeSpan timeout)
=> SentrySdk.FlushAsync(timeout);

/// <inheritdoc cref="IMetricAggregator"/>
public IMetricAggregator Metrics
=> SentrySdk.Metrics;

/// <summary>
/// Forwards the call to <see cref="SentrySdk"/>
/// </summary>
Expand Down
Loading