Skip to content

Conversation

@Flash0ver
Copy link
Member

@Flash0ver Flash0ver commented Jan 9, 2026

Implementation of Trace-connected Metrics
See https://develop.sentry.dev/sdk/telemetry/metrics/

This changeset contains the initial implementation of Trace-connected Metrics for Sentry.

Changes

  • made Batch-Buffer generic, so that it can be used for both Structured Logging and Trace-connected Metrics
  • added new types (SentryTraceMetrics and derived), which follow the same pattern and structure from Structured Logs
  • the SDK-APIs are generic, which are inspired by the System.Diagnostics.Metrics APIs of the BCL / System.Diagnostics.DiagnosticSource package
  • naming of the public APIs differs a bit from the SDK spec in order to be idiomatic .NET
  • currently, made APIs experimental

Please see the discussion comments below to discuss these design decisions.

Related changesets

Related issues and discussions

Follow-ups

Enable public beta

  • Sentry Docs: dotnet platform
  • Sentry Docs: Supported Platforms overview
  • Sentry Onboarding
  • then, enable in Sentry "Platform Categories"

@Flash0ver Flash0ver self-assigned this Jan 9, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 9, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 4a080e7

@codecov
Copy link

codecov bot commented Jan 9, 2026

Codecov Report

❌ Patch coverage is 72.38372% with 95 lines in your changes missing coverage. Please review.
✅ Project coverage is 73.76%. Comparing base (f2ea5c4) to head (4a080e7).

Files with missing lines Patch % Lines
src/Sentry/SentryUnits.cs 0.00% 24 Missing ⚠️
src/Sentry/SentryMetric.Factory.cs 65.85% 14 Missing ⚠️
src/Sentry/Internal/DefaultSentryTraceMetrics.cs 68.42% 9 Missing and 3 partials ⚠️
src/Sentry/Internal/Polyfills.cs 0.00% 10 Missing ⚠️
src/Sentry/SentryMetric.cs 87.50% 7 Missing and 2 partials ⚠️
src/Sentry/SentryTraceMetrics.Distribution.cs 33.33% 8 Missing ⚠️
src/Sentry/SentryTraceMetrics.Gauge.cs 33.33% 8 Missing ⚠️
src/Sentry/SentryTraceMetrics.Counter.cs 50.00% 4 Missing ⚠️
src/Sentry/BindableSentryOptions.cs 25.00% 2 Missing and 1 partial ⚠️
src/Sentry/Internal/DisabledSentryTraceMetrics.cs 71.42% 2 Missing ⚠️
... and 1 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4834      +/-   ##
==========================================
- Coverage   73.84%   73.76%   -0.09%     
==========================================
  Files         483      495      +12     
  Lines       17577    17893     +316     
  Branches     3464     3512      +48     
==========================================
+ Hits        12979    13198     +219     
- Misses       3742     3832      +90     
- Partials      856      863       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Flash0ver Flash0ver marked this pull request as ready for review January 9, 2026 21:09
Comment on lines 170 to 175
public void SetAttribute(string key, object value)
{
_attributes ??= new Dictionary<string, object>();

_attributes[key] = new SentryAttribute(value);
}

This comment was marked as outdated.

Copy link
Member Author

Choose a reason for hiding this comment

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

fixed in e65db5f

bruno-garcia added a commit to getsentry/symbol-collector that referenced this pull request Jan 11, 2026
…rics

Upgrades Sentry .NET SDK from 6.0.0 to 6.1.0-alpha.1 to test the new
experimental trace-connected metrics API from PR getsentry/sentry-dotnet#4834.

Changes:
- Upgrade Sentry SDK to 6.1.0-alpha.1
- Add SentryClientMetrics decorator that emits metrics to Sentry
- Enable experimental metrics in all apps (Server, Console, Android)
- Use SentryClientMetrics in DI registrations

The new metrics API provides:
- AddCounter: for counting events (files, uploads, errors)
- RecordDistribution: for value distributions (uploaded bytes)
- RecordGauge: for point-in-time values (jobs in flight)

Metrics are automatically correlated with the active trace/span.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
bruno-garcia added a commit to getsentry/symbol-collector that referenced this pull request Jan 11, 2026
…rics

Upgrades Sentry .NET SDK from 6.0.0 to 6.1.0-alpha.1 to test the new
experimental trace-connected metrics API from PR getsentry/sentry-dotnet#4834.

Changes:
- Upgrade Sentry SDK to 6.1.0-alpha.1
- Add SentryClientMetrics decorator that emits metrics to Sentry
- Enable experimental metrics in all apps (Server, Console, Android)
- Use SentryClientMetrics in DI registrations (Core, Server, Console)
- Fix duplicate ClientMetrics registration in Core/Startup.cs

The new metrics API provides:
- AddCounter: for counting events (files, uploads, errors)
- RecordDistribution: for value distributions (uploaded bytes)
- RecordGauge: for point-in-time values (jobs in flight)

Metrics are automatically correlated with the active trace/span.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
bruno-garcia added a commit to getsentry/symbol-collector that referenced this pull request Jan 11, 2026
…rics

Upgrades Sentry .NET SDK from 6.0.0 to 6.1.0-alpha.1 to test the new
experimental trace-connected metrics API from PR getsentry/sentry-dotnet#4834.

Changes:
- Upgrade Sentry SDK to 6.1.0-alpha.1
- Add SentryClientMetrics decorator that emits metrics to Sentry
- Make ClientMetrics methods virtual for proper polymorphism
- Enable experimental metrics in all apps (Server, Console, Android)
- Use SentryClientMetrics in DI registrations (Core, Server, Console)
- Fix duplicate ClientMetrics registration in Core/Startup.cs

The new metrics API provides:
- AddCounter: for counting events (files, uploads, errors)
- RecordDistribution: for value distributions (uploaded bytes)
- RecordGauge: for point-in-time values (jobs in flight)

Metrics are automatically correlated with the active trace/span.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>
bruno-garcia added a commit to getsentry/symbol-collector that referenced this pull request Jan 12, 2026
#252)

* feat: upgrade Sentry SDK to 6.1.0-alpha.1 and add trace-connected metrics

Upgrades Sentry .NET SDK from 6.0.0 to 6.1.0-alpha.1 to test the new
experimental trace-connected metrics API from PR getsentry/sentry-dotnet#4834.

Changes:
- Upgrade Sentry SDK to 6.1.0-alpha.1
- Add SentryClientMetrics decorator that emits metrics to Sentry
- Make ClientMetrics methods virtual for proper polymorphism
- Enable experimental metrics in all apps (Server, Console, Android)
- Use SentryClientMetrics in DI registrations (Core, Server, Console)
- Fix duplicate ClientMetrics registration in Core/Startup.cs

The new metrics API provides:
- AddCounter: for counting events (files, uploads, errors)
- RecordDistribution: for value distributions (uploaded bytes)
- RecordGauge: for point-in-time values (jobs in flight)

Metrics are automatically correlated with the active trace/span.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* test: add unit tests for SentryClientMetrics

Adds tests to verify that:
- SentryClientMetrics emits trace_metric items to Sentry
- All metric types (Counter, Distribution, Gauge) are emitted
- Base class counters are also incremented (dual emission)
- Polymorphism works correctly (override vs new)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* refactor: use IHub for SentryClientMetrics to improve testability

- SentryClientMetrics now accepts IHub in constructor (defaults to HubAdapter.Instance)
- Tests use isolated SDK instances with recording transport
- Each test initializes/disposes its own SDK for proper isolation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <[email protected]>

* Delete test/SymbolCollector.Core.Tests/SentryClientMetricsTests.cs

---------

Co-authored-by: Claude Opus 4.5 <[email protected]>
Flash0ver and others added 4 commits January 16, 2026 13:21
Provides hierarchical constants for metric units supported by Sentry Relay,
organized into Duration, Information, and Fraction categories.

Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
/// <param name="value">The value of the metric.</param>
/// <typeparam name="T">The numeric type of the metric.</typeparam>
/// <remarks>Supported numeric value types for <typeparamref name="T"/> are <see langword="byte"/>, <see langword="short"/>, <see langword="int"/>, <see langword="long"/>, <see langword="float"/>, and <see langword="double"/>.</remarks>
public void EmitCounter<T>(string name, T value) where T : struct
Copy link
Member Author

@Flash0ver Flash0ver Jan 19, 2026

Choose a reason for hiding this comment

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

question: discuss identifiers of public method groups

See spec in dev docs Metrics > Metrics Module

-Sentry.metrics.count(..)
+SentrySdk.Metrics.EmitCounter(..);
-Sentry.metrics.gauge(..)
+SentrySdk.Metrics.EmitGauge(..);
-Sentry.metrics.distribution(..)
+SentrySdk.Metrics.EmitDistribution(..);
  • count is both a verb and a noun
  • gauge is both a verb and a noun
  • distribution is a noun only

So my thought was to - in particular for Distribution - use a verb as a prefix to form a verb phrase.
And then - for consistency - use a verb as a prefix for all three method groups.

The respective .NET Metrics (and Open Telemetry) are

using System.Diagnostics.Metrics;

static Meter meter = new Meter(name: "my-meter");

static Counter<int> counter = meter.CreateCounter<int>(name: "my-counter");
static Gauge<int> gauge = meter.CreateGauge<int>(name: "my-gauge");
static Histogram<int> histogram = meter.CreateHistogram<int>(name: "my-histogram");

counter.Add(delta: 1);
gauge.Record(value: 2);
histogram.Record(value: 3);

The first draft started with

SentrySdk.Metrics.AddCounter
SentrySdk.Metrics.RecordGauge
SentrySdk.Metrics.RecordDistribution

although with the verbs consistent with .NET/Open-Telemtry, these verbs do not fit, as they may suggest client-side aggregation, rather than sending the metric as-provided to Sentry with query-time aggregation at Sentry.

Then changing to the verb Emit. This verb is also used in the dev docs. The verb Emit is also used in Logs in Sentry for Go.

So the current naming scheme is, almost, Emit{Type}.
However, currently, instead of EmitCount, I decided to use EmitCounter instead, to be closer to the .NET BLC / System.Diagnostics.DiagnosticSource NuGet package.

An argument can be made to instead be consistent with the spec ... or at least more consistent with the spec. So here are some alternatives up for discussion.

// "type": "counter"
SentrySdk.Metrics.Count() // as in spec: "Sentry.metrics.count()"
SentrySdk.Metrics.EmitCount() // as verb phrase
SentrySdk.Metrics.EmitCounter() // Counter instead of Count, for consistency with the actual type name

// "type": "gauge"
SentrySdk.Metrics.Gauge() // as in spec: "Sentry.metrics.gauge()"
SentrySdk.Metrics.EmitGauge() // as verb phrase

// "type": "distribution"
SentrySdk.Metrics.Distribution() // as in spec: "Sentry.metrics.distribution()"
SentrySdk.Metrics.EmitDistribution() // as verb phrase

What do you prefer?

UPDATE: oh no ... I just realized we had old metrics before ... should we restore (or adapt parts of) that API shape?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think we have to worry about the API shape of the previous metrics product we had. I think the naming as you have it is fine.

/// <param name="value">The value of the metric.</param>
/// <typeparam name="T">The numeric type of the metric.</typeparam>
/// <remarks>Supported numeric value types for <typeparamref name="T"/> are <see langword="byte"/>, <see langword="short"/>, <see langword="int"/>, <see langword="long"/>, <see langword="float"/>, and <see langword="double"/>.</remarks>
public void EmitGauge<T>(string name, T value) where T : struct
Copy link
Member Author

@Flash0ver Flash0ver Jan 19, 2026

Choose a reason for hiding this comment

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

question: Overloads and Parameters of Method Groups

The SDK spec Metrics > Metrics Module suggests these parameters for the three methods Sentry.metrics.count, Sentry.metrics.gauge, and Sentry.metrics.distribution:

  • name, String, required
  • value, Number, required
  • options, Object, optional
    • unit, String, optional, only for distribution and gauge, should not be an enum
    • attributes, Object, optional
    • scope, Scope, optional

name

I decided to have several overloads per method group, rather than a single method per type. This is also what the Meter type / Instrument types of the net6.0+ BCL APIs do.

value

With .NET being typed, I decided to make the APIs generic, as this is also what the .NET BCL / Open Telemetry / System.Diagnostics.DiagnosticSource NuGet package does.
This supports the numeric types byte, short, int, long, float, double. But don't support decimal (.NET Instruments do support it) as it's 128-bit, and Sentry only supports 64-bit signed integral types and 64-bit floating-point numbers.

options

Instead of an Options-Bag, I went with a method group and respective overloads, as again, they are similar to the System.Diagnostics.Metrics APIs.
However, if we'd like, we could do a struct-based Options-bag, per type (struct CounterOptions, struct GaugeOptions, and struct DistributionOptions).

unit

The unit overload only exists in the Gauge and Distribution method groups.
Typed to string, rather than Sentry.MeasurementUnit, as the SDK spec suggests to:

SDKs must not restrict what can be sent in (e.g. by using an enum) but should offer constants or similar that help customers send in units we support.

We could, however, offer an overload that takes Sentry.MeasurementUnit instead of a string.
Or we could add this overload later on.
The motivation of having a string rather than an enum is that Sentry may start supporting more Units at some time, and SDK users should be able to pass them once supported without upgrading the SDK.
Currently, a "custom" unit is not supported, and Relay will either discard or set the Unit to None if an unsupported unit is passed by the user --- the metric itself will not be discarded in that case.

attributes

Offer both an IEnumerable<KeyValuePair<string, object>>, and a ReadOnlySpan<KeyValuePair<string, object>> overload, again, very similar to "tags" of System.Diagnostics.Metrics.

scope

Just a nullable Scope.
Currently not available, but we could now - or later - add an overload for passing a Scope without a unit:
..(string name, T value, Scope? scope)


What do you think?

UPDATE: oh no ... I just realized we had old metrics before ... should we restore (or adapt parts of) that API shape?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of an Options-Bag, I went with a method group and respective overloads, as again, they are similar to the System.Diagnostics.Metrics APIs.

Using an Options type would mean less overloads to maintain... and if the options type was sealed then we could add members to it later. It's probably easier and less ceremony for SDK users to use various overloads with the options they care about.

It really depends how many dimensions the options type exposes... eventually (like with the SentryOptions) the only practical way to set these is via some kind of callback/delegate.

I think it's fine as is for now.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Currently not available, but we could now - or later - add an overload for passing a Scope without a unit:
..(string name, T value, Scope? scope)

What was the rational for omitting this overload currently?

Copy link
Member Author

Choose a reason for hiding this comment

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

Scope currently does not have Attributes yet: opened #4882.
Also the Scope type isn't too prominent yet::

  • SentrySdk.ConfigureScope doesn't return a scope .. but the user could "capture" it out of the delegate
  • SentrySdk.PushScope returns an IDisposable (instance of internal ScopeSnapshot)

I was thinking of adding it when we've added Attributes to Scope in the follow-up.
But we could add and approve it right away to get feedback on the full set of overloads during the experimental phase.

/// Supported numeric value types for <typeparamref name="T"/> are <see langword="byte"/>, <see langword="short"/>, <see langword="int"/>, <see langword="long"/>, <see langword="float"/>, and <see langword="double"/>.
/// </remarks>
/// <seealso href="https://develop.sentry.dev/sdk/telemetry/metrics/"/>
public void SetBeforeSendMetric<T>(Func<SentryMetric<T>, SentryMetric<T>?> beforeSendMetric) where T : struct
Copy link
Member Author

@Flash0ver Flash0ver Jan 19, 2026

Choose a reason for hiding this comment

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

question: Design

With the Metric type being generic, supporting byte, short, int, long, float, and double, this API is also quite similar to the MeterListener of System.Diagnostics.Metrics.
Where you can set one callback per metric type via SetMeasurementEventCallback.

See Collect metrics.

What do you think?

UPDATE: oh no ... I just realized we had old metrics before ... should we restore (or adapt parts of) that API shape?

Copy link
Collaborator

@jamescrosswell jamescrosswell Jan 20, 2026

Choose a reason for hiding this comment

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

It's a pain since the SDK user may want a callback like:

  if (metric.attributes.contains(a => a.name == "foo"))
  {
    return null;
  }

But they'd need to define that function once for each numeric type our metrics support and if we add support for new numeric types their code might break. It doesn't feel like a great API design.

An alternative option (not saying it's better, but just to consider) would be to have the parameter to the callback be a flattening of the various generic types... e.g.

SentryMetricArgType
{
    SentryMetricType type;
    string name;
    object value;
    string? unit;
    IEnumerable<KeyValuePair<string, object>> attributes;
    Scope? scope;
}

That might be a bit messy: impedance mismatch, mappings, type safety issues etc. but it might be better than the alternative.

A more complex variant would be to pass something like a SentryMetricTypeAccessor that mitigated some of the type safety issues by exposing properties of the metric that the SDK user might want to read via getter methods and exposed properties the SDK user might want to modify (if any) via setter methods... so they could do something like:

options.Metrics.SetBeforeSend(accessor => {
  if (accessor.GetMetricValue() is double && accessor.Attributes.Contains("foo"))
  {
   return null;
  }
});

Probably have to play around with different options to see how the implementation and SDK usage feels in practice. I could see what we have in this PR at the moment being pretty onerous for SDK users though, so I think we need to find a better option.

What solution have the other strongly typed SDKs (like Java) opted for here?

Copy link
Member Author

Choose a reason for hiding this comment

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

re: Attributes
I'd like to "fix" them during a separate follow-up PR, if you don't mind,
to get a dedicated design review on this API / these APIs,
as it will impact not only Metrics, but Logs and Scopes (for now) as well.
Opened #4882.

For now, I went with similar SetAttribute/TryGetAttribute methods as we have for Logs.
We haven't "burned" the public identifier Attributes on Logs yet, so we can then adapt the same Collection-based property for Logs as well, after shipping and testing it during the experimental phase for Metrics.

Copy link
Member Author

Choose a reason for hiding this comment

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

re: generic SetBeforeSendMetric Options-API
You are right ... if we'd add a new Value-Type (Relay/Sentry may support 128-bit integral/floating-point numbers later on), this would be a breaking change indeed.

Other typed SDKs just have a double.
sentry-cocoa, having Metrics in Swift, uses UInt for count and Double for distribution+gauge.

I started out with a double as well, but ran into a loss-of-precision problem during testing when converting from float:

Metrics.EmitCounter<float>("", 1.1f); // { "value": 1.1 }
Metrics.EmitCounter<double>("", 1.1d); // { "value": 1.1 }
Metrics.EmitCounter<double>("", 1.1f); // { "value": 1.100000023841858 }

Well ... we could argue

  • the potential imprecision when floats should be used are neglectable
  • Relay/Sentry probably won't support > 64-bit numbers anytime soon ... maybe ever

So maybe just a double is perfectly fine ... similar to the "old" Metrics 🤔

/// <remarks>
/// Experimental features are subject to binary, source and behavioral breaking changes in future updates.
/// </remarks>
public ExperimentalSentryOptions Experimental { get; }
Copy link
Member Author

Choose a reason for hiding this comment

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

question: Experimental vs Stable.

Do we want to publish it as experimental first ... or stable directly?

Copy link
Collaborator

Choose a reason for hiding this comment

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

There's quite a lot of code so we could publish it as experimental for one point release... try to get some feedback from SDK customers using it in anger. There may be strong opinions some of the design decisions (e.g. method groups vs. options types/callbacks) so good to have the flexibility to revisit some of those decisions for a wee while if need be.

Otherwise it's more of a commercial question (is Sentry sure we're going to GA this metrics product?). I assume we captured enough learnings from the first metrics product to be pretty confident of the design and cost structure this time around. @dingsdax ?

Copy link
Member Author

Choose a reason for hiding this comment

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

We'll release it as Experimental feature initially, but going stable by March.


namespace Sentry.Testing;

public sealed class InMemorySentryTraceMetrics : SentryTraceMetrics
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where does this get used?

Copy link
Member Author

@Flash0ver Flash0ver Jan 28, 2026

Choose a reason for hiding this comment

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

In the test.
See #4839.
I split this up poorly.

Before the final review/approval, we should indeed merge #4839 and #4841 (both targeting this branch) into this branch before,
which I split up in the hopes of making the initial review easier.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's merge them now... the code is tightly coupled anyway - I think it's harder to review having them in separate PRs.

/// Defaults to <see langword="true"/>.
/// </summary>
/// <seealso href="https://develop.sentry.dev/sdk/telemetry/metrics/"/>
public bool EnableMetrics { get; set; } = true;
Copy link

Choose a reason for hiding this comment

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

Experimental metrics enabled by default, unlike logs

Low Severity

The EnableMetrics property defaults to true, while the similar EnableLogs property defaults to false. Both are telemetry features that create BatchProcessor infrastructure, but they have inconsistent default behaviors. This means SDK users upgrading will automatically have metrics infrastructure created even though it's marked as experimental, whereas logs require explicit opt-in. Experimental features typically default to disabled to require deliberate opt-in.

Fix in Cursor Fix in Web

Copy link
Collaborator

Choose a reason for hiding this comment

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

That's a fair comment... enabling by default will result in build warnings or failures for folks upgrading to the new version. If it's experimental, we should disable by default.

Copy link
Member Author

Choose a reason for hiding this comment

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

It was discussed whether the default for Metrics be true or false.
The decision was made to be true per default. In particular because we don't have a default integration (currently) and the user needs to actively use the Metrics-APIs in order to use Sentry Metrics.

Moreover the boolean flag has no influence on any experimental build warnings, as the SDK-APIs need to be used actively. I'd like to keep the default here to true.

https://develop.sentry.dev/sdk/telemetry/metrics/#initialization-options


Debug.Assert(hub is not Hub, "In case of a 'full' Hub, there is always a Scope. Otherwise (disabled) there is no Scope, but this branch should be unreachable.");
traceId = SentryId.Empty;
}
Copy link

Choose a reason for hiding this comment

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

Duplicate GetTraceIdAndSpanId method between logs and metrics

Low Severity

The GetTraceIdAndSpanId method in SentryMetric.Factory.cs is nearly identical to the one in SentryLog.cs. Both methods retrieve trace and span IDs from an active span or scope's propagation context, with only a minor comment difference. This duplicated logic increases maintenance burden and risks inconsistent bug fixes if changes are made to one but not the other.

Fix in Cursor Fix in Web

{
SetAttribute("sentry.sdk.version", version);
}
}
Copy link

Choose a reason for hiding this comment

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

Duplicate SetDefaultAttributes method between logs and metrics

Low Severity

The SetDefaultAttributes method in SentryMetric.cs is identical to the one in SentryLog.cs. Both set the same four attributes (sentry.environment, sentry.release, sentry.sdk.name, sentry.sdk.version) with identical logic. This duplication increases maintenance burden and risks inconsistent implementation.

Fix in Cursor Fix in Web


internal void Apply(Scope? scope)
{
}
Copy link

Choose a reason for hiding this comment

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

Empty Apply method is called but does nothing

Low Severity

The Apply(Scope? scope) method in SentryMetric has an empty body but is actively called from SentryMetric.Create in the factory. This is dead code that adds unnecessary complexity. Unlike SentryLog, which doesn't have an Apply method at all, this suggests incomplete implementation or premature scaffolding.

Additional Locations (1)

Fix in Cursor Fix in Web

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.


internal ExperimentalSentryOptions(SentryOptions options)
{
_options = options;
Copy link

Choose a reason for hiding this comment

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

Unused _options field in ExperimentalSentryOptions

Low Severity

The _options field in ExperimentalSentryOptions is declared and assigned in the constructor but never read or used anywhere in the class. This is dead code that clutters the codebase and may confuse future developers about its intended purpose.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants