Skip to content

Commit 202b83f

Browse files
fix: transaction timestamp trimming (#1916)
* Fix child timestamp trimming * Update CHANGELOG * Run formatting * Update docs * Revert * Update dart/test/sentry_tracer_test.dart Co-authored-by: Philipp Hofmann <[email protected]> * change var to final * fix test --------- Co-authored-by: Philipp Hofmann <[email protected]>
1 parent f4bda4c commit 202b83f

File tree

3 files changed

+42
-9
lines changed

3 files changed

+42
-9
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## Unreleased
44

5+
### Fixes
6+
7+
- Fix transaction end timestamp trimming ([#1916](https://github.com/getsentry/sentry-dart/pull/1916))
8+
- Transaction end timestamps are now correctly trimmed to the latest child span end timestamp
9+
510
### Features
611

712
- Use `recordHttpBreadcrumbs` to set iOS `enableNetworkBreadcrumbs` ([#1884](https://github.com/getsentry/sentry-dart/pull/1884))

dart/lib/src/sentry_tracer.dart

+15-9
Original file line numberDiff line numberDiff line change
@@ -109,18 +109,24 @@ class SentryTracer extends ISentrySpan {
109109
}
110110

111111
var _rootEndTimestamp = commonEndTimestamp;
112+
113+
// Trim the end timestamp of the transaction to the very last timestamp of child spans
112114
if (_trimEnd && children.isNotEmpty) {
113-
final childEndTimestamps = children
114-
.where((child) => child.endTimestamp != null)
115-
.map((child) => child.endTimestamp!);
116-
117-
if (childEndTimestamps.isNotEmpty) {
118-
final oldestChildEndTimestamp =
119-
childEndTimestamps.reduce((a, b) => a.isAfter(b) ? a : b);
120-
if (_rootEndTimestamp.isAfter(oldestChildEndTimestamp)) {
121-
_rootEndTimestamp = oldestChildEndTimestamp;
115+
DateTime? latestEndTime;
116+
117+
for (final child in children) {
118+
final childEndTimestamp = child.endTimestamp;
119+
if (childEndTimestamp != null) {
120+
if (latestEndTime == null ||
121+
childEndTimestamp.isAfter(latestEndTime)) {
122+
latestEndTime = child.endTimestamp;
123+
}
122124
}
123125
}
126+
127+
if (latestEndTime != null) {
128+
_rootEndTimestamp = latestEndTime;
129+
}
124130
}
125131

126132
// the callback should run before because if the span is finished,

dart/test/sentry_tracer_test.dart

+22
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,28 @@ void main() {
386386
expect(sut.endTimestamp, endTimestamp);
387387
});
388388

389+
test('end trimmed to latest child end timestamp', () async {
390+
final sut = fixture.getSut(trimEnd: true);
391+
final rootEndInitial = getUtcDateTime();
392+
final childAEnd = rootEndInitial;
393+
final childBEnd = rootEndInitial.add(Duration(seconds: 1));
394+
final childCEnd = rootEndInitial;
395+
396+
final childA = sut.startChild('operation-a', description: 'description');
397+
final childB = sut.startChild('operation-b', description: 'description');
398+
final childC = sut.startChild('operation-c', description: 'description');
399+
400+
await childA.finish(endTimestamp: childAEnd);
401+
await childB.finish(endTimestamp: childBEnd);
402+
await childC.finish(endTimestamp: childCEnd);
403+
404+
await sut.finish(endTimestamp: rootEndInitial);
405+
406+
expect(sut.endTimestamp, equals(childB.endTimestamp),
407+
reason:
408+
'The root end timestamp should be updated to match the latest child end timestamp.');
409+
});
410+
389411
test('does not add more spans than configured in options', () async {
390412
fixture.hub.options.maxSpans = 2;
391413
final sut = fixture.getSut();

0 commit comments

Comments
 (0)