Skip to content

Commit

Permalink
feat: add span level measurements #1855 (#2214)
Browse files Browse the repository at this point in the history
* feat: add span level measurements

* add changelog entry

* add issue link to changelog

* fix: correct changelog

* moved the stored measurements from root span to tracer

* changed issue number to pr number in changelog

* fixed formatting

* Update CHANGELOG.md

Co-authored-by: Giancarlo Buenaflor <giancarlobuenaflor97@gmail.com>

---------

Co-authored-by: Martin <martin@haintz.dev>
Co-authored-by: Giancarlo Buenaflor <giancarlobuenaflor97@gmail.com>
  • Loading branch information
3 people authored Aug 6, 2024
1 parent 384a55c commit 7ec9238
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 8 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Unreleased

### Features

- Add support for span level measurements. ([#2214](https://github.com/getsentry/sentry-dart/pull/2214))

## 8.6.0

### Improvements
Expand Down
7 changes: 6 additions & 1 deletion dart/lib/src/protocol/sentry_span.dart
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,12 @@ class SentrySpan extends ISentrySpan {
num value, {
SentryMeasurementUnit? unit,
}) {
_tracer.setMeasurement(name, value, unit: unit);
if (finished) {
_hub.options.logger(SentryLevel.debug,
"The span is already finished. Measurement $name cannot be set");
return;
}
_tracer.setMeasurementFromChild(name, value, unit: unit);
}

@override
Expand Down
2 changes: 1 addition & 1 deletion dart/lib/src/sentry_span_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ abstract class ISentrySpan {
/// Returns the trace information that could be sent as a sentry-trace header.
SentryTraceHeader toSentryTrace();

/// Set observed measurement for this transaction.
/// Set observed measurement for this span or transaction.
void setMeasurement(
String name,
num value, {
Expand Down
19 changes: 13 additions & 6 deletions dart/lib/src/sentry_tracer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ class SentryTracer extends ISentrySpan {
late final SentrySpan _rootSpan;
final List<SentrySpan> _children = [];
final Map<String, dynamic> _extra = {};

final Map<String, SentryMeasurement> _measurements = {};
Map<String, SentryMeasurement> get measurements => _measurements;

Timer? _autoFinishAfterTimer;
Duration? _autoFinishAfter;
Expand Down Expand Up @@ -320,10 +322,6 @@ class SentryTracer extends ISentrySpan {
@override
SentryTraceHeader toSentryTrace() => _rootSpan.toSentryTrace();

@visibleForTesting
Map<String, SentryMeasurement> get measurements =>
Map.unmodifiable(_measurements);

bool _haveAllChildrenFinished() {
for (final child in children) {
if (!child.finished) {
Expand All @@ -341,10 +339,19 @@ class SentryTracer extends ISentrySpan {
@override
void setMeasurement(String name, num value, {SentryMeasurementUnit? unit}) {
if (finished) {
_hub.options.logger(SentryLevel.debug,
"The tracer is already finished. Measurement $name cannot be set");
return;
}
final measurement = SentryMeasurement(name, value, unit: unit);
_measurements[name] = measurement;
_measurements[name] = SentryMeasurement(name, value, unit: unit);
}

void setMeasurementFromChild(String name, num value,
{SentryMeasurementUnit? unit}) {
// We don't want to overwrite span measurement, if it comes from a child.
if (!_measurements.containsKey(name)) {
setMeasurement(name, value, unit: unit);
}
}

@override
Expand Down
15 changes: 15 additions & 0 deletions dart/test/sentry_span_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,21 @@ void main() {
expect(fixture.hub.options.enableSpanLocalMetricAggregation, false);
expect(sut.localMetricsAggregator, null);
});

test('setMeasurement sets a measurement', () async {
final sut = fixture.getSut();
sut.setMeasurement("test", 1);
expect(sut.tracer.measurements.containsKey("test"), true);
expect(sut.tracer.measurements["test"]!.value, 1);
});

test('setMeasurement does not set a measurement if a span is finished',
() async {
final sut = fixture.getSut();
await sut.finish();
sut.setMeasurement("test", 1);
expect(sut.tracer.measurements.isEmpty, true);
});
}

class Fixture {
Expand Down
16 changes: 16 additions & 0 deletions dart/test/sentry_tracer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,22 @@ void main() {
expect(fixture.hub.options.enableSpanLocalMetricAggregation, false);
expect(sut.localMetricsAggregator, null);
});

test('setMeasurement sets a measurement', () async {
final sut = fixture.getSut();
sut.setMeasurement("test", 1);
expect(sut.measurements.containsKey("test"), true);
expect(sut.measurements["test"]!.value, 1);
});

test('setMeasurementFromChild does not override existing measurements',
() async {
final sut = fixture.getSut();
sut.setMeasurement("test", 1);
sut.setMeasurementFromChild("test", 5);
expect(sut.measurements.containsKey("test"), true);
expect(sut.measurements["test"]!.value, 1);
});
});

group('$SentryBaggageHeader', () {
Expand Down

0 comments on commit 7ec9238

Please sign in to comment.