Skip to content

Commit 52e500e

Browse files
committed
update
1 parent 3a985bd commit 52e500e

File tree

4 files changed

+125
-99
lines changed

4 files changed

+125
-99
lines changed

dart/lib/src/sentry_options.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ class SentryOptions {
378378
bool enableSpotlight = false;
379379

380380
/// The Spotlight URL. Defaults to http://localhost:8969/stream
381-
String spotlightUrl = 'http://localhost:8969/stream';
381+
String spotlightUrl = 'http://10.0.2.2:8969/stream';
382382

383383
SentryOptions({this.dsn, PlatformChecker? checker}) {
384384
if (checker != null) {

dart/lib/src/transport/http_transport.dart

Lines changed: 5 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ import 'dart:async';
22
import 'dart:convert';
33

44
import 'package:http/http.dart';
5+
import 'http_transport_request_creator.dart';
56

67
import '../client_reports/client_report_recorder.dart';
78
import '../client_reports/discard_reason.dart';
89
import 'data_category.dart';
9-
import 'noop_encode.dart' if (dart.library.io) 'encode.dart';
1010
import '../noop_client.dart';
1111
import '../protocol.dart';
1212
import '../sentry_options.dart';
@@ -24,9 +24,7 @@ class HttpTransport implements Transport {
2424

2525
final ClientReportRecorder _recorder;
2626

27-
late _CredentialBuilder _credentialBuilder;
28-
29-
final Map<String, String> _headers;
27+
late HttpTransportRequestCreator _httpTransportRequestCreator;
3028

3129
factory HttpTransport(SentryOptions options, RateLimiter rateLimiter) {
3230
if (options.httpClient is NoOpClient) {
@@ -38,15 +36,8 @@ class HttpTransport implements Transport {
3836

3937
HttpTransport._(this._options, this._rateLimiter)
4038
: _dsn = Dsn.parse(_options.dsn!),
41-
_recorder = _options.recorder,
42-
_headers = _buildHeaders(
43-
_options.platformChecker.isWeb,
44-
_options.sentryClientName,
45-
) {
46-
_credentialBuilder = _CredentialBuilder(
47-
_dsn,
48-
_options.sentryClientName,
49-
);
39+
_recorder = _options.recorder {
40+
_httpTransportRequestCreator = HttpTransportRequestCreator(_options, _dsn.postUri);
5041
}
5142

5243
@override
@@ -57,7 +48,7 @@ class HttpTransport implements Transport {
5748
}
5849
filteredEnvelope.header.sentAt = _options.clock();
5950

60-
final streamedRequest = await _createStreamedRequest(filteredEnvelope);
51+
final streamedRequest = await _httpTransportRequestCreator.createRequest(filteredEnvelope);
6152
final response = await _options.httpClient
6253
.send(streamedRequest)
6354
.then(Response.fromStream);
@@ -95,27 +86,6 @@ class HttpTransport implements Transport {
9586
return SentryId.fromId(eventId);
9687
}
9788

98-
Future<StreamedRequest> _createStreamedRequest(
99-
SentryEnvelope envelope) async {
100-
final streamedRequest = StreamedRequest('POST', _dsn.postUri);
101-
102-
if (_options.compressPayload) {
103-
final compressionSink = compressInSink(streamedRequest.sink, _headers);
104-
envelope
105-
.envelopeStream(_options)
106-
.listen(compressionSink.add)
107-
.onDone(compressionSink.close);
108-
} else {
109-
envelope
110-
.envelopeStream(_options)
111-
.listen(streamedRequest.sink.add)
112-
.onDone(streamedRequest.sink.close);
113-
}
114-
streamedRequest.headers.addAll(_credentialBuilder.configure(_headers));
115-
116-
return streamedRequest;
117-
}
118-
11989
void _updateRetryAfterLimits(Response response) {
12090
// seconds
12191
final retryAfterHeader = response.headers['Retry-After'];
@@ -131,51 +101,3 @@ class HttpTransport implements Transport {
131101
sentryRateLimitHeader, retryAfterHeader, response.statusCode);
132102
}
133103
}
134-
135-
class _CredentialBuilder {
136-
final String _authHeader;
137-
138-
_CredentialBuilder._(String authHeader) : _authHeader = authHeader;
139-
140-
factory _CredentialBuilder(Dsn dsn, String sdkIdentifier) {
141-
final authHeader = _buildAuthHeader(
142-
publicKey: dsn.publicKey,
143-
secretKey: dsn.secretKey,
144-
sdkIdentifier: sdkIdentifier,
145-
);
146-
147-
return _CredentialBuilder._(authHeader);
148-
}
149-
150-
static String _buildAuthHeader({
151-
required String publicKey,
152-
String? secretKey,
153-
required String sdkIdentifier,
154-
}) {
155-
var header = 'Sentry sentry_version=7, sentry_client=$sdkIdentifier, '
156-
'sentry_key=$publicKey';
157-
158-
if (secretKey != null) {
159-
header += ', sentry_secret=$secretKey';
160-
}
161-
162-
return header;
163-
}
164-
165-
Map<String, String> configure(Map<String, String> headers) {
166-
return headers
167-
..addAll(
168-
<String, String>{'X-Sentry-Auth': _authHeader},
169-
);
170-
}
171-
}
172-
173-
Map<String, String> _buildHeaders(bool isWeb, String sdkIdentifier) {
174-
final headers = {'Content-Type': 'application/x-sentry-envelope'};
175-
// NOTE(lejard_h) overriding user agent on VM and Flutter not sure why
176-
// for web it use browser user agent
177-
if (!isWeb) {
178-
headers['User-Agent'] = sdkIdentifier;
179-
}
180-
return headers;
181-
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import 'package:http/http.dart';
2+
import 'package:meta/meta.dart';
3+
4+
import '../../sentry.dart';
5+
import 'encode.dart';
6+
7+
@internal
8+
class HttpTransportRequestCreator {
9+
final SentryOptions _options;
10+
final Dsn _dsn;
11+
final Map<String, String> _headers;
12+
final Uri _requestUri;
13+
late _CredentialBuilder _credentialBuilder;
14+
15+
HttpTransportRequestCreator(this._options, this._requestUri)
16+
: _dsn = Dsn.parse(_options.dsn!),
17+
_headers = _buildHeaders(
18+
_options.platformChecker.isWeb,
19+
_options.sentryClientName,
20+
) {
21+
_credentialBuilder = _CredentialBuilder(
22+
_dsn,
23+
_options.sentryClientName,
24+
);
25+
}
26+
27+
Future<StreamedRequest> createRequest(SentryEnvelope envelope) async {
28+
final streamedRequest = StreamedRequest('POST', _requestUri);
29+
30+
if (_options.compressPayload) {
31+
final compressionSink =
32+
compressInSink(streamedRequest.sink, _headers);
33+
envelope
34+
.envelopeStream(_options)
35+
.listen(compressionSink.add)
36+
.onDone(compressionSink.close);
37+
} else {
38+
envelope
39+
.envelopeStream(_options)
40+
.listen(streamedRequest.sink.add)
41+
.onDone(streamedRequest.sink.close);
42+
}
43+
44+
streamedRequest.headers.addAll(_credentialBuilder.configure(_headers));
45+
return streamedRequest;
46+
}
47+
}
48+
49+
Map<String, String> _buildHeaders(bool isWeb, String sdkIdentifier) {
50+
final headers = {'Content-Type': 'application/x-sentry-envelope'};
51+
// NOTE(lejard_h) overriding user agent on VM and Flutter not sure why
52+
// for web it use browser user agent
53+
if (!isWeb) {
54+
headers['User-Agent'] = sdkIdentifier;
55+
}
56+
return headers;
57+
}
58+
59+
class _CredentialBuilder {
60+
final String _authHeader;
61+
62+
_CredentialBuilder._(String authHeader) : _authHeader = authHeader;
63+
64+
factory _CredentialBuilder(Dsn dsn, String sdkIdentifier) {
65+
final authHeader = _buildAuthHeader(
66+
publicKey: dsn.publicKey,
67+
secretKey: dsn.secretKey,
68+
sdkIdentifier: sdkIdentifier,
69+
);
70+
71+
return _CredentialBuilder._(authHeader);
72+
}
73+
74+
static String _buildAuthHeader({
75+
required String publicKey,
76+
String? secretKey,
77+
required String sdkIdentifier,
78+
}) {
79+
var header = 'Sentry sentry_version=7, sentry_client=$sdkIdentifier, '
80+
'sentry_key=$publicKey';
81+
82+
if (secretKey != null) {
83+
header += ', sentry_secret=$secretKey';
84+
}
85+
86+
return header;
87+
}
88+
89+
Map<String, String> configure(Map<String, String> headers) {
90+
return headers
91+
..addAll(
92+
<String, String>{'X-Sentry-Auth': _authHeader},
93+
);
94+
}
95+
}

dart/lib/src/transport/spotlight_http_transport.dart

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
import 'package:http/http.dart';
2+
import 'http_transport_request_creator.dart';
23

34
import '../../sentry.dart';
45
import '../client_reports/discard_reason.dart';
6+
import '../noop_client.dart';
57
import 'data_category.dart';
68

7-
/// Spotlight HTTP transport class that sends Sentry envelopes to both Sentry and Spotlight.
9+
/// Spotlight HTTP transport decorator that sends Sentry envelopes to both Sentry and Spotlight.
810
class SpotlightHttpTransport extends Transport {
911
final SentryOptions _options;
1012
final Transport _transport;
11-
final Map<String, String> _headers = {'Content-Type': 'application/x-sentry-envelope'};
13+
final HttpTransportRequestCreator _requestCreator;
14+
15+
factory SpotlightHttpTransport(SentryOptions options, Transport transport) {
16+
if (options.httpClient is NoOpClient) {
17+
options.httpClient = Client();
18+
}
19+
return SpotlightHttpTransport._(options, transport);
20+
}
21+
22+
SpotlightHttpTransport._(this._options, this._transport) :
23+
_requestCreator =
24+
HttpTransportRequestCreator(_options, Uri.parse(_options.spotlightUrl));
1225

13-
SpotlightHttpTransport(this._options, this._transport);
1426

1527
@override
1628
Future<SentryId?> send(SentryEnvelope envelope) async {
@@ -19,16 +31,13 @@ class SpotlightHttpTransport extends Transport {
1931
}
2032

2133
Future<void> _sendToSpotlight(SentryEnvelope envelope) async {
22-
final Uri spotlightUri = Uri.parse(_options.spotlightUrl);
23-
final StreamedRequest spotlightRequest =
24-
StreamedRequest('POST', spotlightUri);
34+
envelope.header.sentAt = _options.clock();
2535

26-
envelope
27-
.envelopeStream(_options)
28-
.listen(spotlightRequest.sink.add)
29-
.onDone(spotlightRequest.sink.close);
36+
// Screenshots do not work currently https://github.com/getsentry/spotlight/issues/274
37+
envelope.items
38+
.removeWhere((element) => element.header.contentType == 'image/png');
3039

31-
spotlightRequest.headers.addAll(_headers);
40+
final spotlightRequest = await _requestCreator.createRequest(envelope);
3241

3342
final response = await _options.httpClient
3443
.send(spotlightRequest)
@@ -40,20 +49,20 @@ class SpotlightHttpTransport extends Transport {
4049
if (_options.debug) {
4150
_options.logger(
4251
SentryLevel.error,
43-
'Spotlight Sidecar API returned an error, statusCode = ${response.statusCode}, '
52+
'Spotlight returned an error, statusCode = ${response.statusCode}, '
4453
'body = ${response.body}',
4554
);
4655
print('body = ${response.request}');
4756
}
4857

4958
if (response.statusCode >= 400 && response.statusCode != 429) {
50-
_options.recorder.recordLostEvent(
51-
DiscardReason.networkError, DataCategory.error);
59+
_options.recorder
60+
.recordLostEvent(DiscardReason.networkError, DataCategory.error);
5261
}
5362
} else {
5463
_options.logger(
5564
SentryLevel.debug,
56-
'Envelope ${envelope.header.eventId ?? "--"} was sent successfully to spotlight ($spotlightUri)',
65+
'Envelope ${envelope.header.eventId ?? "--"} was sent successfully to Spotlight (${_options.spotlightUrl})',
5766
);
5867
}
5968
}

0 commit comments

Comments
 (0)