Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

### Features

- Add `Sentry.setAttributes` and `Sentry.removeAttribute` ([#3352](https://github.com/getsentry/sentry-dart/pull/3352))
- These attributes are set at the scope level and apply to all logs (and later to metrics and spans).
- When a scope attribute conflicts with a log-level attribute, the log-level attribute always takes precedence.

### Fixes

- Android app crashing on hot-restart in debug mode ([#3358](https://github.com/getsentry/sentry-dart/pull/3358))
Expand Down
28 changes: 26 additions & 2 deletions packages/dart/lib/src/hub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ class Hub {
if (!_isEnabled) {
_options.log(
SentryLevel.warning,
"Instance is disabled and this 'captureFeedback' call is a no-op.",
"Instance is disabled and this 'captureLog' call is a no-op.",
);
} else {
final item = _peek();
Expand Down Expand Up @@ -341,7 +341,31 @@ class Hub {
return scope;
}

/// Adds a breacrumb to the current Scope
void setAttributes(Map<String, SentryAttribute> attributes) {
if (!_isEnabled) {
_options.log(
SentryLevel.warning,
"Instance is disabled and this 'setAttributes' call is a no-op.",
);
} else {
final item = _peek();
item.scope.setAttributes(attributes);
}
}

void removeAttribute(String key) {
if (!_isEnabled) {
_options.log(
SentryLevel.warning,
"Instance is disabled and this 'removeAttribute' call is a no-op.",
);
} else {
final item = _peek();
item.scope.removeAttribute(key);
}
}

/// Adds a breadcrumb to the current Scope
Future<void> addBreadcrumb(Breadcrumb crumb, {Hint? hint}) async {
if (!_isEnabled) {
_options.log(
Expand Down
7 changes: 7 additions & 0 deletions packages/dart/lib/src/hub_adapter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -199,4 +199,11 @@ class HubAdapter implements Hub {

@override
FutureOr<void> captureLog(SentryLog log) => Sentry.currentHub.captureLog(log);

@override
void setAttributes(Map<String, SentryAttribute> attributes) =>
Sentry.currentHub.setAttributes(attributes);

@override
void removeAttribute(String key) => Sentry.currentHub.removeAttribute(key);
}
6 changes: 3 additions & 3 deletions packages/dart/lib/src/logs_enricher_integration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'sdk_lifecycle_hooks.dart';
import 'utils/os_utils.dart';
import 'integration.dart';
import 'hub.dart';
import 'protocol/sentry_log_attribute.dart';
import 'protocol/sentry_attribute.dart';
import 'sentry_options.dart';

@internal
Expand All @@ -20,12 +20,12 @@ class LogsEnricherIntegration extends Integration<SentryOptions> {
final os = getSentryOperatingSystem();

if (os.name != null) {
event.log.attributes['os.name'] = SentryLogAttribute.string(
event.log.attributes['os.name'] = SentryAttribute.string(
os.name ?? '',
);
}
if (os.version != null) {
event.log.attributes['os.version'] = SentryLogAttribute.string(
event.log.attributes['os.version'] = SentryAttribute.string(
os.version ?? '',
);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/dart/lib/src/noop_hub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,10 @@ class NoOpHub implements Hub {

@override
Scope get scope => Scope(_options);

@override
void setAttributes(Map<String, SentryAttribute> attributes) {}

@override
void removeAttribute(String key) {}
}
2 changes: 1 addition & 1 deletion packages/dart/lib/src/protocol.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ export 'protocol/sentry_feature_flag.dart';
export 'protocol/sentry_feature_flags.dart';
export 'protocol/sentry_log.dart';
export 'protocol/sentry_log_level.dart';
export 'protocol/sentry_log_attribute.dart';
export 'protocol/sentry_attribute.dart';
54 changes: 54 additions & 0 deletions packages/dart/lib/src/protocol/sentry_attribute.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'package:meta/meta.dart';

@Deprecated('Use SentryAttribute instead')
class SentryLogAttribute extends SentryAttribute {
SentryLogAttribute._(super.value, super.type);

factory SentryLogAttribute.string(String value) {
return SentryLogAttribute._(value, 'string');
}

factory SentryLogAttribute.bool(bool value) {
return SentryLogAttribute._(value, 'boolean');
}

factory SentryLogAttribute.int(int value) {
return SentryLogAttribute._(value, 'integer');
}

factory SentryLogAttribute.double(double value) {
return SentryLogAttribute._(value, 'double');
}
}

class SentryAttribute {
@internal
final String type;
final dynamic value;

@internal
SentryAttribute(this.value, this.type);

factory SentryAttribute.string(String value) {
return SentryAttribute(value, 'string');
}

factory SentryAttribute.bool(bool value) {
return SentryAttribute(value, 'boolean');
}

factory SentryAttribute.int(int value) {
return SentryAttribute(value, 'integer');
}

factory SentryAttribute.double(double value) {
return SentryAttribute(value, 'double');
}

Map<String, dynamic> toJson() {
return {
'value': value,
'type': type,
};
}
}
4 changes: 2 additions & 2 deletions packages/dart/lib/src/protocol/sentry_log.dart
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import 'sentry_attribute.dart';
import 'sentry_id.dart';
import 'sentry_log_level.dart';
import 'sentry_log_attribute.dart';

class SentryLog {
DateTime timestamp;
SentryId traceId;
SentryLogLevel level;
String body;
Map<String, SentryLogAttribute> attributes;
Map<String, SentryAttribute> attributes;
int? severityNumber;

/// The traceId is initially an empty default value and is populated during event processing;
Expand Down
30 changes: 0 additions & 30 deletions packages/dart/lib/src/protocol/sentry_log_attribute.dart

This file was deleted.

19 changes: 19 additions & 0 deletions packages/dart/lib/src/scope.dart
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ class Scope {

List<SentryAttachment> get attachments => List.unmodifiable(_attachments);

final Map<String, SentryAttribute> _attributes = {};

Map<String, SentryAttribute> get attributes => Map.unmodifiable(_attributes);

Scope(this._options);

Breadcrumb? _addBreadCrumbSync(Breadcrumb breadcrumb, Hint hint) {
Expand Down Expand Up @@ -222,6 +226,16 @@ class Scope {
}
}

void setAttributes(Map<String, SentryAttribute> attributes) {
attributes.forEach((key, value) {
_attributes[key] = value;
});
}

void removeAttribute(String key) {
_attributes.remove(key);
}

void addAttachment(SentryAttachment attachment) {
_attachments.add(attachment);
}
Expand Down Expand Up @@ -258,6 +272,7 @@ class Scope {
_eventProcessors.clear();
_replayId = null;
propagationContext = PropagationContext();
_attributes.clear();

_clearBreadcrumbsSync();
_setUserSync(null);
Expand Down Expand Up @@ -461,6 +476,10 @@ class Scope {
clone.addAttachment(attachment);
}

if (_attributes.isNotEmpty) {
clone.setAttributes(Map.from(_attributes));
}

return clone;
}

Expand Down
13 changes: 13 additions & 0 deletions packages/dart/lib/src/sentry.dart
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,19 @@ class Sentry {
static Future<void> addBreadcrumb(Breadcrumb crumb, {Hint? hint}) =>
_hub.addBreadcrumb(crumb, hint: hint);

/// Adds attributes to the current [Scope].
/// These attributes will be applied to logs.
/// When the same attribute keys exist on the current log,
/// it takes precedence over an attribute with the same key set on any scope.
static void setAttributes(Map<String, SentryAttribute> attributes) {
_hub.setAttributes(attributes);
}

/// Removes the attribute [key] from the scope.
static void removeAttribute(String key) {
_hub.removeAttribute(key);
}

/// Configures the scope through the callback.
static FutureOr<void> configureScope(ScopeCallback callback) =>
_hub.configureScope(callback);
Expand Down
21 changes: 13 additions & 8 deletions packages/dart/lib/src/sentry_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -502,21 +502,26 @@ class SentryClient {
return;
}

log.attributes['sentry.sdk.name'] = SentryLogAttribute.string(
if (scope != null) {
final merged = Map.of(scope.attributes)..addAll(log.attributes);
log.attributes = merged;
}

log.attributes['sentry.sdk.name'] = SentryAttribute.string(
_options.sdk.name,
);
log.attributes['sentry.sdk.version'] = SentryLogAttribute.string(
log.attributes['sentry.sdk.version'] = SentryAttribute.string(
_options.sdk.version,
);
final environment = _options.environment;
if (environment != null) {
log.attributes['sentry.environment'] = SentryLogAttribute.string(
log.attributes['sentry.environment'] = SentryAttribute.string(
environment,
);
}
final release = _options.release;
if (release != null) {
log.attributes['sentry.release'] = SentryLogAttribute.string(
log.attributes['sentry.release'] = SentryAttribute.string(
release,
);
}
Expand All @@ -527,7 +532,7 @@ class SentryClient {
}
final span = scope?.span;
if (span != null) {
log.attributes['sentry.trace.parent_span_id'] = SentryLogAttribute.string(
log.attributes['sentry.trace.parent_span_id'] = SentryAttribute.string(
span.context.spanId.toString(),
);
}
Expand All @@ -537,13 +542,13 @@ class SentryClient {
final email = user?.email;
final name = user?.name;
if (id != null) {
log.attributes['user.id'] = SentryLogAttribute.string(id);
log.attributes['user.id'] = SentryAttribute.string(id);
}
if (name != null) {
log.attributes['user.name'] = SentryLogAttribute.string(name);
log.attributes['user.name'] = SentryAttribute.string(name);
}
if (email != null) {
log.attributes['user.email'] = SentryLogAttribute.string(email);
log.attributes['user.email'] = SentryAttribute.string(email);
}

final beforeSendLog = _options.beforeSendLog;
Expand Down
Loading
Loading