Skip to content

Commit dc54bfc

Browse files
vaindbruno-garciadenrasestefanosiano
authored
feat: profiling for iOS/macOS (#1611)
Co-authored-by: Bruno Garcia <[email protected]> Co-authored-by: Denis Andrašec <[email protected]> Co-authored-by: Stefano <[email protected]>
1 parent 677b331 commit dc54bfc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1454
-563
lines changed

.github/workflows/analyze.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ jobs:
6060
timeout-minutes: 20
6161
steps:
6262
- uses: actions/checkout@v3
63+
- name: Apply dependency override
64+
if: ${{ inputs.package == 'flutter' }}
65+
working-directory: ${{ inputs.package }}
66+
run: |
67+
sed -i.bak 's|sentry:.*|sentry:\n path: /github/workspace/dart|g' pubspec.yaml
6368
- uses: axel-op/dart-package-analyzer@7a6c3c66bce78d82b729a1ffef2d9458fde6c8d2 # pin@v3
6469
id: analysis
6570
with:

.github/workflows/flutter.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ jobs:
116116
with:
117117
path: "./flutter/coverage/lcov.info"
118118
min_coverage: 90
119+
exclude: "lib/src/native/cocoa/binding.dart"
119120

120121
- name: Build ${{ matrix.target }}
121122
run: |

.github/workflows/flutter_test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ jobs:
104104
avd-name: macOS-avd-x86_64-31
105105
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
106106
disable-animations: true
107-
script: flutter test integration_test --verbose
107+
script: flutter test integration_test/all.dart --verbose
108108

109109
cocoa:
110110
name: "${{ matrix.target }} | ${{ matrix.sdk }}"
@@ -155,7 +155,7 @@ jobs:
155155
- name: run integration test
156156
# Disable flutter integration tests for iOS for now (https://github.com/getsentry/sentry-dart/issues/1605#issuecomment-1695809346)
157157
if: ${{ matrix.target != 'ios' }}
158-
run: flutter test -d "${{ steps.device.outputs.name }}" integration_test --verbose
158+
run: flutter test -d "${{ steps.device.outputs.name }}" integration_test/all.dart --verbose
159159

160160
- name: run native test
161161
# We only have the native unit test package in the iOS xcodeproj at the moment.

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
### Features
6+
7+
- Initial (alpha) support for profiling on iOS and macOS ([#1611](https://github.com/getsentry/sentry-dart/pull/1611))
8+
39
## 7.11.0
410

511
### Fixes

dart/analysis_options.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ include: package:lints/recommended.yaml
33
analyzer:
44
exclude:
55
- example/** # the example has its own 'analysis_options.yaml'
6+
- test/*.mocks.dart
67
errors:
78
# treat missing required parameters as a warning (not a hint)
89
missing_required_param: error

dart/lib/src/hub.dart

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:async';
22
import 'dart:collection';
33

44
import 'package:meta/meta.dart';
5+
import 'profiling.dart';
56
import 'propagation_context.dart';
67
import 'transport/data_category.dart';
78

@@ -435,12 +436,12 @@ class Hub {
435436
} else {
436437
final item = _peek();
437438

438-
final samplingContext = SentrySamplingContext(
439-
transactionContext, customSamplingContext ?? {});
440-
441439
// if transactionContext has no sampled decision, run the traces sampler
442-
if (transactionContext.samplingDecision == null) {
443-
final samplingDecision = _tracesSampler.sample(samplingContext);
440+
var samplingDecision = transactionContext.samplingDecision;
441+
if (samplingDecision == null) {
442+
final samplingContext = SentrySamplingContext(
443+
transactionContext, customSamplingContext ?? {});
444+
samplingDecision = _tracesSampler.sample(samplingContext);
444445
transactionContext =
445446
transactionContext.copyWith(samplingDecision: samplingDecision);
446447
}
@@ -451,6 +452,12 @@ class Hub {
451452
);
452453
}
453454

455+
SentryProfiler? profiler;
456+
if (_profilerFactory != null &&
457+
_tracesSampler.sampleProfiling(samplingDecision)) {
458+
profiler = _profilerFactory?.startProfiler(transactionContext);
459+
}
460+
454461
final tracer = SentryTracer(
455462
transactionContext,
456463
this,
@@ -459,6 +466,7 @@ class Hub {
459466
autoFinishAfter: autoFinishAfter,
460467
trimEnd: trimEnd ?? false,
461468
onFinish: onFinish,
469+
profiler: profiler,
462470
);
463471
if (bindToScope ?? false) {
464472
item.scope.span = tracer;
@@ -554,6 +562,14 @@ class Hub {
554562
) =>
555563
_throwableToSpan.add(throwable, span, transaction);
556564

565+
@internal
566+
SentryProfilerFactory? get profilerFactory => _profilerFactory;
567+
568+
@internal
569+
set profilerFactory(SentryProfilerFactory? value) => _profilerFactory = value;
570+
571+
SentryProfilerFactory? _profilerFactory;
572+
557573
SentryEvent _assignTraceContext(SentryEvent event) {
558574
// assign trace context
559575
if (event.throwable != null && event.contexts.trace == null) {

dart/lib/src/hub_adapter.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:meta/meta.dart';
44
import 'hint.dart';
55

66
import 'hub.dart';
7+
import 'profiling.dart';
78
import 'protocol.dart';
89
import 'scope.dart';
910
import 'sentry.dart';
@@ -168,6 +169,16 @@ class HubAdapter implements Hub {
168169
) =>
169170
Sentry.currentHub.setSpanContext(throwable, span, transaction);
170171

172+
@internal
173+
@override
174+
set profilerFactory(SentryProfilerFactory? value) =>
175+
Sentry.currentHub.profilerFactory = value;
176+
177+
@internal
178+
@override
179+
SentryProfilerFactory? get profilerFactory =>
180+
Sentry.currentHub.profilerFactory;
181+
171182
@override
172183
Scope get scope => Sentry.currentHub.scope;
173184
}

dart/lib/src/noop_hub.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:meta/meta.dart';
44

55
import 'hint.dart';
66
import 'hub.dart';
7+
import 'profiling.dart';
78
import 'protocol.dart';
89
import 'scope.dart';
910
import 'sentry_client.dart';
@@ -120,6 +121,14 @@ class NoOpHub implements Hub {
120121
@override
121122
void setSpanContext(throwable, ISentrySpan span, String transaction) {}
122123

124+
@internal
125+
@override
126+
set profilerFactory(SentryProfilerFactory? value) {}
127+
128+
@internal
129+
@override
130+
SentryProfilerFactory? get profilerFactory => null;
131+
123132
@override
124133
Scope get scope => Scope(_options);
125134
}

dart/lib/src/profiling.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'dart:async';
2+
3+
import 'package:meta/meta.dart';
4+
5+
import '../sentry.dart';
6+
7+
@internal
8+
abstract class SentryProfilerFactory {
9+
SentryProfiler? startProfiler(SentryTransactionContext context);
10+
}
11+
12+
@internal
13+
abstract class SentryProfiler {
14+
Future<SentryProfileInfo?> finishFor(SentryTransaction transaction);
15+
void dispose();
16+
}
17+
18+
// See https://develop.sentry.dev/sdk/profiles/
19+
@internal
20+
abstract class SentryProfileInfo {
21+
SentryEnvelopeItem asEnvelopeItem();
22+
}

dart/lib/src/protocol/sentry_event.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class SentryEvent with SentryEventLike<SentryEvent> {
5959
/// The ID Sentry.io assigned to the submitted event for future reference.
6060
final SentryId eventId;
6161

62-
/// A timestamp representing when the breadcrumb occurred.
62+
/// A timestamp representing when the event occurred.
6363
final DateTime? timestamp;
6464

6565
/// A string representing the platform the SDK is submitting from. This will be used by the Sentry interface to customize various components in the interface.

0 commit comments

Comments
 (0)