From 5420d74fb297d21d80947e0567098cf820f90565 Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Tue, 28 Jan 2025 11:37:18 +0100 Subject: [PATCH 1/4] document how to attach data to all transactions and its spans --- .../data-to-all-spans/android.mdx | 38 +++++++++++++ .../configuration/data-to-all-spans/java.mdx | 38 +++++++++++++ .../data-to-all-spans/java.spring-boot.mdx | 54 +++++++++++++++++++ .../data-to-all-spans/java.spring.mdx | 54 +++++++++++++++++++ .../performance/improving-data/android.mdx | 6 +++ .../performance/improving-data/java.mdx | 6 +++ 6 files changed, 196 insertions(+) create mode 100644 platform-includes/configuration/data-to-all-spans/android.mdx create mode 100644 platform-includes/configuration/data-to-all-spans/java.mdx create mode 100644 platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx create mode 100644 platform-includes/configuration/data-to-all-spans/java.spring.mdx diff --git a/platform-includes/configuration/data-to-all-spans/android.mdx b/platform-includes/configuration/data-to-all-spans/android.mdx new file mode 100644 index 0000000000000..36bbf2f655a85 --- /dev/null +++ b/platform-includes/configuration/data-to-all-spans/android.mdx @@ -0,0 +1,38 @@ +```java +Sentry.init(options -> { + options.setBeforeSendTransaction((transaction, hint) -> { + // set the attribute on the root span + if (transaction.getContexts().getTrace() == null) { + transaction.getContexts().getTrace().getData().put("myAttribute", "myValue"); + } + + // and on all child spans + transaction.getSpans().forEach(span -> { + if (span.getData() != null) { + span.getData().put("myAttribute", "myValue"); + } + }); + + return transaction; + }); +}); +``` +```kotlin +Sentry.init(options -> { + options.setBeforeSendTransaction((transaction, hint) -> { + // set the attribute on the root span + transaction.contexts.trace?.data?.let { data -> + data["myAttribute"] = "myValue" + } + + // and on all child spans + transaction.spans.forEach(Consumer { span: SentrySpan -> + span.data?.let { data -> + data["myAttribute"] = "myValue" + } + }) + + transaction + }); +}); +``` \ No newline at end of file diff --git a/platform-includes/configuration/data-to-all-spans/java.mdx b/platform-includes/configuration/data-to-all-spans/java.mdx new file mode 100644 index 0000000000000..36bbf2f655a85 --- /dev/null +++ b/platform-includes/configuration/data-to-all-spans/java.mdx @@ -0,0 +1,38 @@ +```java +Sentry.init(options -> { + options.setBeforeSendTransaction((transaction, hint) -> { + // set the attribute on the root span + if (transaction.getContexts().getTrace() == null) { + transaction.getContexts().getTrace().getData().put("myAttribute", "myValue"); + } + + // and on all child spans + transaction.getSpans().forEach(span -> { + if (span.getData() != null) { + span.getData().put("myAttribute", "myValue"); + } + }); + + return transaction; + }); +}); +``` +```kotlin +Sentry.init(options -> { + options.setBeforeSendTransaction((transaction, hint) -> { + // set the attribute on the root span + transaction.contexts.trace?.data?.let { data -> + data["myAttribute"] = "myValue" + } + + // and on all child spans + transaction.spans.forEach(Consumer { span: SentrySpan -> + span.data?.let { data -> + data["myAttribute"] = "myValue" + } + }) + + transaction + }); +}); +``` \ No newline at end of file diff --git a/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx b/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx new file mode 100644 index 0000000000000..3ef44e69f5254 --- /dev/null +++ b/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx @@ -0,0 +1,54 @@ +```java +import io.sentry.SentryTransaction; +import io.sentry.SentryOptions; +import io.sentry.Hint +import org.springframework.stereotype.Component; + +@Component +public class CustomBeforeSendTransactionCallback implements SentryOptions.BeforeSendTransactionCallback { + @Override + public SentryTransaction execute(SentryTransaction transaction, Hint hint) { + + // set the attribute on the root span + if (transaction.getContexts().getTrace() != null) { + transaction.getContexts().getTrace().getData().put("myAttribute", "myValue"); + } + + // and on all child spans + transaction.getSpans().forEach(span -> { + if (span.getData() != null) { + span.getData().put("myAttribute", "myValue"); + } + }); + + return transaction; + } +} +``` + +```kotlin +import io.sentry.SentryTransaction +import io.sentry.SentryOptions +import io.sentry.Hint +import org.springframework.stereotype.Component + +@Component +class CustomBeforeSendTransactionCallback : SentryOptions.BeforeSendTransactionCallback { + override fun execute(transaction: SentryTransaction, hint: Hint): SentryTransaction? { + + // set the attribute on the root span + transaction.contexts.trace?.data?.let { data -> + data["myAttribute"] = "myValue" + } + + // and on all child spans + transaction.spans.forEach { span -> + span.data?.let { data -> + data["myAttribute"] = "myValue" + } + } + + transaction + } +} +``` diff --git a/platform-includes/configuration/data-to-all-spans/java.spring.mdx b/platform-includes/configuration/data-to-all-spans/java.spring.mdx new file mode 100644 index 0000000000000..87fab31a742d8 --- /dev/null +++ b/platform-includes/configuration/data-to-all-spans/java.spring.mdx @@ -0,0 +1,54 @@ +```java +io.sentry.protocol.SentryTransaction; +import io.sentry.SentryOptions; +import io.sentry.Hint; +import org.springframework.stereotype.Component; + +@Component +public class CustomBeforeSendTransactionCallback implements SentryOptions.BeforeSendTransactionCallback { + @Override + public SentryTransaction execute(SentryTransaction transaction, Hint hint) { + + // set the attribute on the root span + if (transaction.getContexts().getTrace() != null) { + transaction.getContexts().getTrace().getData().put("myAttribute", "myValue"); + } + + // and on all child spans + transaction.getSpans().forEach(span -> { + if (span.getData() != null) { + span.getData().put("myAttribute", "myValue"); + } + }); + + return transaction; + } +} +``` + +```kotlin +import io.sentry.protocol.SentryTransaction +import io.sentry.SentryOptions +import io.sentry.Hint +import org.springframework.stereotype.Component + +@Component +class CustomBeforeSendTransactionCallback : SentryOptions.BeforeSendTransactionCallback { + override fun execute(transaction: SentryTransaction, hint: Hint): SentryTransaction? { + + // set the attribute on the root span + transaction.contexts.trace?.data?.let { data -> + data["myAttribute"] = "myValue" + } + + // and on all child spans + transaction.spans.forEach { span -> + span.data?.let { data -> + data["myAttribute"] = "myValue" + } + } + + transaction + } +} +``` diff --git a/platform-includes/performance/improving-data/android.mdx b/platform-includes/performance/improving-data/android.mdx index 3e668ced55f58..d540dca1bf679 100644 --- a/platform-includes/performance/improving-data/android.mdx +++ b/platform-includes/performance/improving-data/android.mdx @@ -49,3 +49,9 @@ span.setData("my-data-attribute-4", listOf("value1", "value2", "value3")) span.setData("my-data-attribute-5", listOf(42, 43, 44)) span.setData("my-data-attribute-6", listOf(true, false, true)) ``` + +### Adding Attributes to all Spans and Transactions + +To add an attribute to all spans, use the `beforeSendTransaction` callback: + + \ No newline at end of file diff --git a/platform-includes/performance/improving-data/java.mdx b/platform-includes/performance/improving-data/java.mdx index 3e668ced55f58..d540dca1bf679 100644 --- a/platform-includes/performance/improving-data/java.mdx +++ b/platform-includes/performance/improving-data/java.mdx @@ -49,3 +49,9 @@ span.setData("my-data-attribute-4", listOf("value1", "value2", "value3")) span.setData("my-data-attribute-5", listOf(42, 43, 44)) span.setData("my-data-attribute-6", listOf(true, false, true)) ``` + +### Adding Attributes to all Spans and Transactions + +To add an attribute to all spans, use the `beforeSendTransaction` callback: + + \ No newline at end of file From 5ec701ac75947e78fc355cafb6c79c612518eccd Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Tue, 28 Jan 2025 11:44:22 +0100 Subject: [PATCH 2/4] fix import statement --- .../configuration/data-to-all-spans/java.spring-boot.mdx | 4 ++-- .../configuration/data-to-all-spans/java.spring.mdx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx b/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx index 3ef44e69f5254..49de56c4f3cf1 100644 --- a/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx +++ b/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx @@ -1,5 +1,5 @@ ```java -import io.sentry.SentryTransaction; +import io.sentry.protocol.SentryTransaction; import io.sentry.SentryOptions; import io.sentry.Hint import org.springframework.stereotype.Component; @@ -27,7 +27,7 @@ public class CustomBeforeSendTransactionCallback implements SentryOptions.Before ``` ```kotlin -import io.sentry.SentryTransaction +import io.sentry.protocol.SentryTransaction import io.sentry.SentryOptions import io.sentry.Hint import org.springframework.stereotype.Component diff --git a/platform-includes/configuration/data-to-all-spans/java.spring.mdx b/platform-includes/configuration/data-to-all-spans/java.spring.mdx index 87fab31a742d8..3e1d99d501b48 100644 --- a/platform-includes/configuration/data-to-all-spans/java.spring.mdx +++ b/platform-includes/configuration/data-to-all-spans/java.spring.mdx @@ -1,5 +1,5 @@ ```java -io.sentry.protocol.SentryTransaction; +import io.sentry.protocol.SentryTransaction; import io.sentry.SentryOptions; import io.sentry.Hint; import org.springframework.stereotype.Component; From 79214977ce08c11394db6086e48ce9877f21908c Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Tue, 11 Feb 2025 16:47:24 +0100 Subject: [PATCH 3/4] fix kotlin samples, use setData on trace --- .../data-to-all-spans/android.mdx | 37 +++++++++---------- .../configuration/data-to-all-spans/java.mdx | 37 +++++++++---------- .../data-to-all-spans/java.spring-boot.mdx | 8 ++-- .../data-to-all-spans/java.spring.mdx | 6 +-- 4 files changed, 43 insertions(+), 45 deletions(-) diff --git a/platform-includes/configuration/data-to-all-spans/android.mdx b/platform-includes/configuration/data-to-all-spans/android.mdx index 36bbf2f655a85..a74d3116b156f 100644 --- a/platform-includes/configuration/data-to-all-spans/android.mdx +++ b/platform-includes/configuration/data-to-all-spans/android.mdx @@ -1,38 +1,37 @@ ```java Sentry.init(options -> { options.setBeforeSendTransaction((transaction, hint) -> { - // set the attribute on the root span - if (transaction.getContexts().getTrace() == null) { - transaction.getContexts().getTrace().getData().put("myAttribute", "myValue"); - } + // set the attribute on the root span + if (transaction.getContexts().getTrace() != null) { + transaction.getContexts().getTrace().setData("myAttribute", "myValue"); + } - // and on all child spans - transaction.getSpans().forEach(span -> { - if (span.getData() != null) { + // and on all child spans + transaction.getSpans().forEach(span -> { + if (span.getData() != null) { span.getData().put("myAttribute", "myValue"); - } - }); + } + }); - return transaction; + return transaction; }); }); ``` ```kotlin -Sentry.init(options -> { - options.setBeforeSendTransaction((transaction, hint) -> { +Sentry.init({ options -> + options.setBeforeSendTransaction { transaction, hint -> // set the attribute on the root span - transaction.contexts.trace?.data?.let { data -> - data["myAttribute"] = "myValue" + transaction.contexts.trace?.let { trace -> + trace.setData("myAttribute", "myValue") } - // and on all child spans - transaction.spans.forEach(Consumer { span: SentrySpan -> + transaction.spans.forEach { span -> span.data?.let { data -> data["myAttribute"] = "myValue" } - }) + } transaction - }); -}); + } +}) ``` \ No newline at end of file diff --git a/platform-includes/configuration/data-to-all-spans/java.mdx b/platform-includes/configuration/data-to-all-spans/java.mdx index 36bbf2f655a85..a74d3116b156f 100644 --- a/platform-includes/configuration/data-to-all-spans/java.mdx +++ b/platform-includes/configuration/data-to-all-spans/java.mdx @@ -1,38 +1,37 @@ ```java Sentry.init(options -> { options.setBeforeSendTransaction((transaction, hint) -> { - // set the attribute on the root span - if (transaction.getContexts().getTrace() == null) { - transaction.getContexts().getTrace().getData().put("myAttribute", "myValue"); - } + // set the attribute on the root span + if (transaction.getContexts().getTrace() != null) { + transaction.getContexts().getTrace().setData("myAttribute", "myValue"); + } - // and on all child spans - transaction.getSpans().forEach(span -> { - if (span.getData() != null) { + // and on all child spans + transaction.getSpans().forEach(span -> { + if (span.getData() != null) { span.getData().put("myAttribute", "myValue"); - } - }); + } + }); - return transaction; + return transaction; }); }); ``` ```kotlin -Sentry.init(options -> { - options.setBeforeSendTransaction((transaction, hint) -> { +Sentry.init({ options -> + options.setBeforeSendTransaction { transaction, hint -> // set the attribute on the root span - transaction.contexts.trace?.data?.let { data -> - data["myAttribute"] = "myValue" + transaction.contexts.trace?.let { trace -> + trace.setData("myAttribute", "myValue") } - // and on all child spans - transaction.spans.forEach(Consumer { span: SentrySpan -> + transaction.spans.forEach { span -> span.data?.let { data -> data["myAttribute"] = "myValue" } - }) + } transaction - }); -}); + } +}) ``` \ No newline at end of file diff --git a/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx b/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx index 49de56c4f3cf1..f25f6bbe231df 100644 --- a/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx +++ b/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx @@ -1,7 +1,7 @@ ```java import io.sentry.protocol.SentryTransaction; import io.sentry.SentryOptions; -import io.sentry.Hint +import io.sentry.Hint; import org.springframework.stereotype.Component; @Component @@ -11,7 +11,7 @@ public class CustomBeforeSendTransactionCallback implements SentryOptions.Before // set the attribute on the root span if (transaction.getContexts().getTrace() != null) { - transaction.getContexts().getTrace().getData().put("myAttribute", "myValue"); + transaction.getContexts().getTrace().setData("myAttribute", "myValue"); } // and on all child spans @@ -37,8 +37,8 @@ class CustomBeforeSendTransactionCallback : SentryOptions.BeforeSendTransactionC override fun execute(transaction: SentryTransaction, hint: Hint): SentryTransaction? { // set the attribute on the root span - transaction.contexts.trace?.data?.let { data -> - data["myAttribute"] = "myValue" + transaction.contexts.trace?.let { trace -> + trace.setData("myAttribute", "myValue") } // and on all child spans diff --git a/platform-includes/configuration/data-to-all-spans/java.spring.mdx b/platform-includes/configuration/data-to-all-spans/java.spring.mdx index 3e1d99d501b48..f25f6bbe231df 100644 --- a/platform-includes/configuration/data-to-all-spans/java.spring.mdx +++ b/platform-includes/configuration/data-to-all-spans/java.spring.mdx @@ -11,7 +11,7 @@ public class CustomBeforeSendTransactionCallback implements SentryOptions.Before // set the attribute on the root span if (transaction.getContexts().getTrace() != null) { - transaction.getContexts().getTrace().getData().put("myAttribute", "myValue"); + transaction.getContexts().getTrace().setData("myAttribute", "myValue"); } // and on all child spans @@ -37,8 +37,8 @@ class CustomBeforeSendTransactionCallback : SentryOptions.BeforeSendTransactionC override fun execute(transaction: SentryTransaction, hint: Hint): SentryTransaction? { // set the attribute on the root span - transaction.contexts.trace?.data?.let { data -> - data["myAttribute"] = "myValue" + transaction.contexts.trace?.let { trace -> + trace.setData("myAttribute", "myValue") } // and on all child spans From 994233509a21342f9c61ef9f44ad7eb90092e2b1 Mon Sep 17 00:00:00 2001 From: Lukas Bloder Date: Wed, 12 Feb 2025 20:29:52 +0100 Subject: [PATCH 4/4] fix code samples --- .../data-to-all-spans/android.mdx | 38 +++++++++++-------- .../configuration/data-to-all-spans/java.mdx | 38 +++++++++++-------- .../data-to-all-spans/java.spring-boot.mdx | 21 ++++++---- .../data-to-all-spans/java.spring.mdx | 21 ++++++---- 4 files changed, 72 insertions(+), 46 deletions(-) diff --git a/platform-includes/configuration/data-to-all-spans/android.mdx b/platform-includes/configuration/data-to-all-spans/android.mdx index a74d3116b156f..e875de16ed616 100644 --- a/platform-includes/configuration/data-to-all-spans/android.mdx +++ b/platform-includes/configuration/data-to-all-spans/android.mdx @@ -1,37 +1,45 @@ ```java Sentry.init(options -> { options.setBeforeSendTransaction((transaction, hint) -> { - // set the attribute on the root span - if (transaction.getContexts().getTrace() != null) { + + // set the attribute on the root span + if (transaction.getContexts().getTrace() == null) { + SpanContext spanContext = new SpanContext("op"); + transaction.getContexts().setTrace(spanContext); + } transaction.getContexts().getTrace().setData("myAttribute", "myValue"); - } - // and on all child spans - transaction.getSpans().forEach(span -> { - if (span.getData() != null) { + // and on all child spans + transaction.getSpans().forEach(span -> { + if (span.getData() == null) { + span.setData(new HashMap<>()); + } span.getData().put("myAttribute", "myValue"); - } - }); + }); - return transaction; + return transaction; }); }); ``` ```kotlin -Sentry.init({ options -> +Sentry.init { options -> options.setBeforeSendTransaction { transaction, hint -> + // set the attribute on the root span - transaction.contexts.trace?.let { trace -> - trace.setData("myAttribute", "myValue") + if (transaction.contexts.trace == null) { + transaction.contexts.setTrace(SpanContext("op")) } + transaction.contexts.trace?.setData("myAttribute", "myValue") + // and on all child spans transaction.spans.forEach { span -> - span.data?.let { data -> - data["myAttribute"] = "myValue" + if (span.data == null) { + span.data = HashMap() } + span.data?.set("myAttribute", "myValue") } transaction } -}) +} ``` \ No newline at end of file diff --git a/platform-includes/configuration/data-to-all-spans/java.mdx b/platform-includes/configuration/data-to-all-spans/java.mdx index a74d3116b156f..e875de16ed616 100644 --- a/platform-includes/configuration/data-to-all-spans/java.mdx +++ b/platform-includes/configuration/data-to-all-spans/java.mdx @@ -1,37 +1,45 @@ ```java Sentry.init(options -> { options.setBeforeSendTransaction((transaction, hint) -> { - // set the attribute on the root span - if (transaction.getContexts().getTrace() != null) { + + // set the attribute on the root span + if (transaction.getContexts().getTrace() == null) { + SpanContext spanContext = new SpanContext("op"); + transaction.getContexts().setTrace(spanContext); + } transaction.getContexts().getTrace().setData("myAttribute", "myValue"); - } - // and on all child spans - transaction.getSpans().forEach(span -> { - if (span.getData() != null) { + // and on all child spans + transaction.getSpans().forEach(span -> { + if (span.getData() == null) { + span.setData(new HashMap<>()); + } span.getData().put("myAttribute", "myValue"); - } - }); + }); - return transaction; + return transaction; }); }); ``` ```kotlin -Sentry.init({ options -> +Sentry.init { options -> options.setBeforeSendTransaction { transaction, hint -> + // set the attribute on the root span - transaction.contexts.trace?.let { trace -> - trace.setData("myAttribute", "myValue") + if (transaction.contexts.trace == null) { + transaction.contexts.setTrace(SpanContext("op")) } + transaction.contexts.trace?.setData("myAttribute", "myValue") + // and on all child spans transaction.spans.forEach { span -> - span.data?.let { data -> - data["myAttribute"] = "myValue" + if (span.data == null) { + span.data = HashMap() } + span.data?.set("myAttribute", "myValue") } transaction } -}) +} ``` \ No newline at end of file diff --git a/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx b/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx index f25f6bbe231df..c02cd208afce2 100644 --- a/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx +++ b/platform-includes/configuration/data-to-all-spans/java.spring-boot.mdx @@ -10,15 +10,18 @@ public class CustomBeforeSendTransactionCallback implements SentryOptions.Before public SentryTransaction execute(SentryTransaction transaction, Hint hint) { // set the attribute on the root span - if (transaction.getContexts().getTrace() != null) { - transaction.getContexts().getTrace().setData("myAttribute", "myValue"); + if (transaction.getContexts().getTrace() == null) { + SpanContext spanContext = new SpanContext("op"); + transaction.getContexts().setTrace(spanContext); } + transaction.getContexts().getTrace().setData("myAttribute", "myValue"); // and on all child spans transaction.getSpans().forEach(span -> { - if (span.getData() != null) { - span.getData().put("myAttribute", "myValue"); + if (span.getData() == null) { + span.setData(new HashMap<>()); } + span.getData().put("myAttribute", "myValue"); }); return transaction; @@ -37,15 +40,17 @@ class CustomBeforeSendTransactionCallback : SentryOptions.BeforeSendTransactionC override fun execute(transaction: SentryTransaction, hint: Hint): SentryTransaction? { // set the attribute on the root span - transaction.contexts.trace?.let { trace -> - trace.setData("myAttribute", "myValue") + if (transaction.contexts.trace == null) { + transaction.contexts.setTrace(SpanContext("op")) } + transaction.contexts.trace?.setData("myAttribute", "myValue") // and on all child spans transaction.spans.forEach { span -> - span.data?.let { data -> - data["myAttribute"] = "myValue" + if (span.data == null) { + span.data = HashMap() } + span.data?.set("myAttribute", "myValue") } transaction diff --git a/platform-includes/configuration/data-to-all-spans/java.spring.mdx b/platform-includes/configuration/data-to-all-spans/java.spring.mdx index f25f6bbe231df..c02cd208afce2 100644 --- a/platform-includes/configuration/data-to-all-spans/java.spring.mdx +++ b/platform-includes/configuration/data-to-all-spans/java.spring.mdx @@ -10,15 +10,18 @@ public class CustomBeforeSendTransactionCallback implements SentryOptions.Before public SentryTransaction execute(SentryTransaction transaction, Hint hint) { // set the attribute on the root span - if (transaction.getContexts().getTrace() != null) { - transaction.getContexts().getTrace().setData("myAttribute", "myValue"); + if (transaction.getContexts().getTrace() == null) { + SpanContext spanContext = new SpanContext("op"); + transaction.getContexts().setTrace(spanContext); } + transaction.getContexts().getTrace().setData("myAttribute", "myValue"); // and on all child spans transaction.getSpans().forEach(span -> { - if (span.getData() != null) { - span.getData().put("myAttribute", "myValue"); + if (span.getData() == null) { + span.setData(new HashMap<>()); } + span.getData().put("myAttribute", "myValue"); }); return transaction; @@ -37,15 +40,17 @@ class CustomBeforeSendTransactionCallback : SentryOptions.BeforeSendTransactionC override fun execute(transaction: SentryTransaction, hint: Hint): SentryTransaction? { // set the attribute on the root span - transaction.contexts.trace?.let { trace -> - trace.setData("myAttribute", "myValue") + if (transaction.contexts.trace == null) { + transaction.contexts.setTrace(SpanContext("op")) } + transaction.contexts.trace?.setData("myAttribute", "myValue") // and on all child spans transaction.spans.forEach { span -> - span.data?.let { data -> - data["myAttribute"] = "myValue" + if (span.data == null) { + span.data = HashMap() } + span.data?.set("myAttribute", "myValue") } transaction