Skip to content

Commit 3c482e7

Browse files
committed
timing api uses span duration as value for the emitted metric if possible
1 parent 90a2e0b commit 3c482e7

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

dart/lib/src/metrics/metrics_api.dart

+8-4
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,17 @@ class MetricsApi {
138138
}
139139
} finally {
140140
final after = _hub.options.clock();
141-
final duration = after.difference(before);
141+
Duration duration = after.difference(before);
142+
// If we have a span, we use its duration as value for the emitted metric
143+
if (span != null) {
144+
await span.finish();
145+
duration =
146+
span.endTimestamp?.difference(span.startTimestamp) ?? duration;
147+
}
142148
final value = _convertMicrosTo(unit, duration.inMicroseconds);
143149

144150
_hub.metricsAggregator?.emit(MetricType.distribution, key, value, unit,
145151
_enrichWithDefaultTags(tags));
146-
147-
await span?.finish();
148152
}
149153
}
150154

@@ -156,7 +160,7 @@ class MetricsApi {
156160
case DurationSentryMeasurementUnit.microSecond:
157161
return micros.toDouble();
158162
case DurationSentryMeasurementUnit.milliSecond:
159-
return micros / 1000;
163+
return micros / 1000.0;
160164
case DurationSentryMeasurementUnit.second:
161165
return micros / 1000000.0;
162166
case DurationSentryMeasurementUnit.minute:

dart/test/metrics/metrics_api_test.dart

+14-2
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ void main() {
102102
final delay = Duration(milliseconds: 100);
103103
final completer = Completer<void>();
104104
fixture._options.tracesSampleRate = 1;
105+
fixture._options.enableMetrics = true;
105106
MetricsApi api = fixture.getSut(hub: fixture.hub);
106107

107108
// Start a transaction so that timing api can start a child span
@@ -114,17 +115,28 @@ void main() {
114115

115116
// Timing starts a span
116117
api.timing('my key',
118+
unit: DurationSentryMeasurementUnit.milliSecond,
117119
function: () => Future.delayed(delay, () => completer.complete()));
118120
final span = transaction.children.first;
119121
expect(span.finished, false);
120122
expect(span.context.operation, 'metric.timing');
121123
expect(span.context.description, 'my key');
122-
final spanDuration = span.endTimestamp!.difference(span.startTimestamp);
123124

124125
// Timing finishes the span when the function is finished, which takes 100 milliseconds
125126
await completer.future;
126-
expect(spanDuration.inMilliseconds >= 100, true);
127127
expect(span.finished, true);
128+
final spanDuration = span.endTimestamp!.difference(span.startTimestamp);
129+
expect(spanDuration.inMilliseconds >= 100, true);
130+
await Future.delayed(Duration());
131+
132+
Iterable<Metric> sentMetrics =
133+
fixture.hub.metricsAggregator!.buckets.values.first.values;
134+
135+
// The emitted metric value should match the span duration
136+
expect(sentMetrics.first.unit, DurationSentryMeasurementUnit.milliSecond);
137+
// Duration.inMilliseconds returns an int, so we have to assert it
138+
expect((sentMetrics.first as DistributionMetric).values.first.toInt(),
139+
spanDuration.inMilliseconds);
128140
});
129141
});
130142
}

0 commit comments

Comments
 (0)