From 7bbe8ba632312430b3718ff865c6c4dcfad48030 Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Tue, 1 Jul 2025 12:28:06 -0700 Subject: [PATCH 01/11] [DOCS-9023] Best practices for tracing native iOS Android apps --- .../en/real_user_monitoring/guide/_index.md | 1 + ...actices-tracing-native-ios-android-apps.md | 168 ++++++++++++++++++ 2 files changed, 169 insertions(+) create mode 100644 content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md diff --git a/content/en/real_user_monitoring/guide/_index.md b/content/en/real_user_monitoring/guide/_index.md index b6e577ff6458c..202e2a285e748 100644 --- a/content/en/real_user_monitoring/guide/_index.md +++ b/content/en/real_user_monitoring/guide/_index.md @@ -24,6 +24,7 @@ cascade: {{< nextlink href="real_user_monitoring/guide/best-practices-for-rum-sampling" >}}Best practices for RUM sampling{{< /nextlink >}} {{< nextlink href="real_user_monitoring/guide/debug-symbols" >}}Investigate obfuscated stack traces with RUM debug symbols{{< /nextlink >}} {{< nextlink href="real_user_monitoring/guide/retention_filter_best_practices" >}}Retention filter best practices{{< /nextlink >}} + {{< nextlink href="real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps" >}}Best practices for tracing native iOS and Android apps{{< /nextlink >}} {{< /whatsnext >}} {{< whatsnext desc="Browser RUM:" >}} diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md new file mode 100644 index 0000000000000..e5275b8e7db6c --- /dev/null +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -0,0 +1,168 @@ +--- +title: Best Practices for Tracing Native iOS and Android Apps +description: Learn how to instrument, use, and optimize Datadog's Trace SDK for native iOS and Android apps. +further_reading: +- link: '/real_user_monitoring/connect_rum_and_traces' + tag: 'Documentation' + text: 'Connect RUM and Traces' +- link: '/tracing/trace_collection/automatic_instrumentation/dd_libraries/ios' + tag: 'Documentation' + text: 'iOS Trace SDK' +- link: '/tracing/trace_collection/automatic_instrumentation/dd_libraries/android/' + tag: 'Documentation' + text: 'Android Trace SDK' +- link: '/tracing/trace_collection/custom_instrumentation/ios/otel/' + tag: 'Documentation' + text: 'OpenTelemetry for iOS' +- link: '/tracing/trace_collection/custom_instrumentation/android/otel/' + tag: 'Documentation' + text: 'OpenTelemetry for Android' +--- + +# Overview + +Datadog's Trace SDK for [iOS][1] and [Android][2] lets you add APM spans to your mobile apps. This guide covers usage, key use cases, and sampling, with or without Datadog RUM. + +## Native mobile tracing + +Native mobile tracing allows you to manually instrument spans in your iOS or Android app code, giving you precise control over what operations are measured. Unlike backend APM tracers, which automatically collect spans, mobile tracing requires you to start and stop spans around the specific actions you want to monitor. This approach works independently of Datadog RUM, but can also be used alongside it for deeper visibility into user experiences and backend interactions. + +With Datadog's [Trace SDK for iOS][1] and [Trace SDK for Android][2], you can capture detailed performance data directly from your mobile applications. If you prefer, you can also use [OpenTelemetry for iOS][3] or [OpenTelemetry for Android][4] for custom instrumentation. These tools help you understand app performance, trace requests across services, and optimize both frontend and backend monitoring. + +## Use cases + +### Distributed tracing: frontend-to-backend + +You can create distributed traces that span from your mobile frontend to your backend services. This is possible with or without RUM. For example, you can wrap one or more frontend-to-backend traces under a manually created span using the Trace SDK. + +{{< tabs >}} +{{% tab "iOS" %}} +Use the [manual context propagation][1] to inject trace headers into network requests. Use `setActive()` to link child spans to a parent span ([API reference][2]). + +[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/ios?tab=swiftpackagemanagerspm#:~:text=(Optional)%20To%20distribute%20traces%20between%20your%20environments%2C%20for%20example%20frontend%20%2D%20backend%2C%20you%20can%20either%20do%20it%20manually%20or%20leverage%20our%20auto%20instrumentation.%20In%20both%20cases%2C%20network%20traces%20are%20sampled%20with%20an%20adjustable%20sampling%20rate.%20A%20sampling%20of%2020%25%20is%20applied%20by%20default +[2]: https://swiftpackageindex.com/datadog/dd-sdk-ios/develop/documentation/datadogtrace/otspan/setactive/ + +{{% /tab %}} +{{% tab "Android" %}} + +Use [OkHttp parent span helpers][1] or [OpenTelemetry addParentSpan][2] to link spans across threads. + +[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/android/?tab=kotlin#okhttp +[2]: /tracing/trace_collection/custom_instrumentation/android/otel/?tab=kotlin#:~:text=(Optional)%20Add%20local%20parent%20span%20to%20the%20span%20generated%20around%20the%20OkHttp%20request%20in%20RUM%3A + +{{% /tab %}} +{{< /tabs >}} + +**Note**: Wrapping RUM resource spans under a native span works automatically if the parent span is on the same thread as the network call. Otherwise, use the provided helpers to set the parent span manually. + +### Profiling native application performance + +Instrumenting multiple native spans and linking them (using `setActive` on iOS or `addParentSpan` on Android) allows you to profile key parts of your app. This helps you: +- Understand how different methods and components interact +- Break down performance bottlenecks +- Gain actionable insights into app behavior + +Here's how to manually instrument a span in your mobile app using the Trace SDK: + +{{< tabs >}} +{{% tab "iOS" %}} +```swift +let span = tracer.startSpan(operationName: "") +// ... code to measure ... +span.finish() +``` +See [more iOS examples][1]. + +[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/ios?tab=swiftpackagemanagerspm + +{{% /tab %}} +{{% tab "Android" %}} + +```kotlin +val span = tracer.buildSpan("").start() +// ... code to measure ... +span.finish() +``` +See [more Android examples][1]. + +[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/android/?tab=kotlin + +{{% /tab %}} +{{< /tabs >}} + +### Creating business spans + +The Trace SDK is independent from RUM, so you can track business processes or flows that span multiple screens or views. For example, you can measure how long it takes users to complete a checkout flow, or how long a background sync takes, regardless of RUM session sampling. These business spans appear in the APM UI and can be used for custom metrics and dashboards. + +### Manual span instrumentation example + +Here's how to create a manual span in your mobile app using the Trace SDK: + +{{< tabs >}} +{{% tab "iOS" %}} +```swift +let span = tracer.startSpan(operationName: "") +// ... code to measure ... +span.finish() +``` +See [more iOS examples][1]. + +[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/ios?tab=swiftpackagemanagerspm + +{{% /tab %}} +{{% tab "Android" %}} + +```kotlin +val span = tracer.buildSpan("").start() +// ... code to measure ... +span.finish() +``` +See [more Android examples][1]. + +[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/android/?tab=kotlin + +{{% /tab %}} +{{< /tabs >}} + +## Sampling + +Sampling in native mobile tracing controls which spans and traces appear in the Datadog UI, helping you balance visibility with data volume. All spans you instrument in your app are recorded and sent to Datadog, but only a subset that are based on your sampling rates and are displayed for analysis. + +There are a few sampling rate parameters in the Datadog iOS SDK: + +| Parameter | Description | +|---------------------------------------------|------------------------------------------------------------------| +| `Trace.sampleRate` | Controls the percentage of traces (spans) collected by the tracer.| +| `urlSessionTracking.firstPartyHostsTracing.sampleRate` | Controls the percentage of network requests traced for first-party hosts. | +| `RUM.sessionSampleRate` | Controls the percentage of user sessions that are recorded for RUM.| +| `WebViewTracking.logsSampleRate` | Controls the percentage of logs collected from WebViews. | + +### How sampling works + +- **Local span sampling** applies to spans you create manually in your app. It's controlled by the `Trace.sampleRate` parameter. For example, if you set this rate to 50, all spans are sent, but only 50% are visible in the UI. Each span event includes the `_dd.agent_psr` field (the sampling rate) and `metrics._sampling_priority_v1` (1 for sampled, 0 for not sampled). +- **Distributed trace sampling** applies to traces that cross service boundaries, such as network requests to your backend. This is controlled by the `urlSessionTracking.firstPartyHostsTracing.sampleRate` parameter. If set to 50, only half of backend requests have the sampled flag set to true, as indicated by the [W3C trace context][7]. All Datadog agents honor this decision, so you see 50% of distributed traces in the UI. + +Sampling rates are applied independently. The most restrictive rate determines what data is visible in the UI for a given session or trace. For example: +- If you set a low RUM session sample rate (for example, 1%), only 1% of user sessions are recorded for RUM, but you can still trace all network requests within those sessions by setting the network tracing sample rate to 100%. +- If you set a high trace sample rate but a low RUM sample rate, you may see traces without corresponding RUM data. + +**Example scenario:** +To sample 1% of all app sessions and trace all API networks within those sessions: +- Set `RUM.sessionSampleRate = 1` +- Set `urlSessionTracking.firstPartyHostsTracing.sampleRate = 100` + +Sampling decisions are communicated through trace headers, ensuring all services in a distributed trace use the same sampling choice. + +**Note**: This behavior applies only to iOS SDK `v2.9.0+`. + +## Further Reading + +{{< partial name="whats-next/whats-next.html" >}} + +[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/ios +[2]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/android +[3]: /tracing/trace_collection/custom_instrumentation/ios/otel +[4]: /tracing/trace_collection/custom_instrumentation/android/otel +[5]: https://github.com/DataDog/dd-sdk-ios/blob/develop/DatadogTrace/Sources/TraceConfiguration.swift#L32 +[6]: https://github.com/DataDog/dd-sdk-ios/blob/develop/DatadogTrace/Sources/TraceConfiguration.swift#L106 +[7]: https://www.w3.org/TR/trace-context/#sampled-flag From 0126cfbcc524bfa2a445deaa1cb0a791a38076c7 Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Tue, 1 Jul 2025 12:29:25 -0700 Subject: [PATCH 02/11] separate example --- .../guide/best-practices-tracing-native-ios-android-apps.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index e5275b8e7db6c..f4bfe4f913e01 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -94,9 +94,9 @@ See [more Android examples][1]. The Trace SDK is independent from RUM, so you can track business processes or flows that span multiple screens or views. For example, you can measure how long it takes users to complete a checkout flow, or how long a background sync takes, regardless of RUM session sampling. These business spans appear in the APM UI and can be used for custom metrics and dashboards. -### Manual span instrumentation example +## Manual span instrumentation -Here's how to create a manual span in your mobile app using the Trace SDK: +Here's an example of how to create a manual span in your mobile app using the Trace SDK: {{< tabs >}} {{% tab "iOS" %}} From bbcc68414323868213b48767e545f23109e7c4bc Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Wed, 2 Jul 2025 10:39:17 -0700 Subject: [PATCH 03/11] remove duplicate info --- ...actices-tracing-native-ios-android-apps.md | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index f4bfe4f913e01..42c61d75e55ac 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -94,36 +94,6 @@ See [more Android examples][1]. The Trace SDK is independent from RUM, so you can track business processes or flows that span multiple screens or views. For example, you can measure how long it takes users to complete a checkout flow, or how long a background sync takes, regardless of RUM session sampling. These business spans appear in the APM UI and can be used for custom metrics and dashboards. -## Manual span instrumentation - -Here's an example of how to create a manual span in your mobile app using the Trace SDK: - -{{< tabs >}} -{{% tab "iOS" %}} -```swift -let span = tracer.startSpan(operationName: "") -// ... code to measure ... -span.finish() -``` -See [more iOS examples][1]. - -[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/ios?tab=swiftpackagemanagerspm - -{{% /tab %}} -{{% tab "Android" %}} - -```kotlin -val span = tracer.buildSpan("").start() -// ... code to measure ... -span.finish() -``` -See [more Android examples][1]. - -[1]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/android/?tab=kotlin - -{{% /tab %}} -{{< /tabs >}} - ## Sampling Sampling in native mobile tracing controls which spans and traces appear in the Datadog UI, helping you balance visibility with data volume. All spans you instrument in your app are recorded and sent to Datadog, but only a subset that are based on your sampling rates and are displayed for analysis. From 430dbefeaa8f302ec44fd24298b6c6935317f76a Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Wed, 2 Jul 2025 15:52:56 -0700 Subject: [PATCH 04/11] space --- .../guide/best-practices-tracing-native-ios-android-apps.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index 42c61d75e55ac..931ae0e0382f3 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -25,13 +25,15 @@ Datadog's Trace SDK for [iOS][1] and [Android][2] lets you add APM spans to your ## Native mobile tracing -Native mobile tracing allows you to manually instrument spans in your iOS or Android app code, giving you precise control over what operations are measured. Unlike backend APM tracers, which automatically collect spans, mobile tracing requires you to start and stop spans around the specific actions you want to monitor. This approach works independently of Datadog RUM, but can also be used alongside it for deeper visibility into user experiences and backend interactions. +Native mobile tracing allows you to manually instrument spans in your iOS or Android app code, giving you precise control over what operations are measured. + +Unlike backend APM tracers, which automatically collect spans, mobile tracing requires you to start and stop spans around the specific actions you want to monitor. This approach works independently of Datadog RUM, but can also be used alongside it for deeper visibility into user experiences and backend interactions. With Datadog's [Trace SDK for iOS][1] and [Trace SDK for Android][2], you can capture detailed performance data directly from your mobile applications. If you prefer, you can also use [OpenTelemetry for iOS][3] or [OpenTelemetry for Android][4] for custom instrumentation. These tools help you understand app performance, trace requests across services, and optimize both frontend and backend monitoring. ## Use cases -### Distributed tracing: frontend-to-backend +### Wrap a frontend-to-backend distributed trace under a native span You can create distributed traces that span from your mobile frontend to your backend services. This is possible with or without RUM. For example, you can wrap one or more frontend-to-backend traces under a manually created span using the Trace SDK. From a3fe966b8cd1bfaf91e5dd697e93eb36ec2968ec Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Thu, 3 Jul 2025 14:18:03 -0700 Subject: [PATCH 05/11] small edit --- .../guide/best-practices-tracing-native-ios-android-apps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index 931ae0e0382f3..bec1d94d0e8aa 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -21,7 +21,7 @@ further_reading: # Overview -Datadog's Trace SDK for [iOS][1] and [Android][2] lets you add APM spans to your mobile apps. This guide covers usage, key use cases, and sampling, with or without Datadog RUM. +Datadog's Trace SDK for [iOS][1] and [Android][2] lets you add APM spans to your mobile apps. This guide covers usage, key use cases, and sampling rates, with or without Datadog RUM. ## Native mobile tracing From f81d13064f1d35a9a733c1b2270b501c26e2cb3f Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Fri, 11 Jul 2025 10:26:38 -0700 Subject: [PATCH 06/11] more cohesive --- ...actices-tracing-native-ios-android-apps.md | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index bec1d94d0e8aa..1c85dcbcce75f 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -21,15 +21,11 @@ further_reading: # Overview -Datadog's Trace SDK for [iOS][1] and [Android][2] lets you add APM spans to your mobile apps. This guide covers usage, key use cases, and sampling rates, with or without Datadog RUM. +Datadog's Trace SDK for [iOS][1] and [Android][2] lets you add APM spans to your mobile apps. This guide covers usage, key use cases, and sampling rates, with or without using the Datadog RUM SDK. -## Native mobile tracing +Native mobile tracing gives you precise control over what operations are measured by manually instrumenting spans in your iOS or Android app code. This approach works independently of Datadog RUM, but can also be used alongside it for deeper visibility into user experiences and backend interactions. You can also use [OpenTelemetry for iOS][3] or [OpenTelemetry for Android][4] for custom instrumentation. -Native mobile tracing allows you to manually instrument spans in your iOS or Android app code, giving you precise control over what operations are measured. - -Unlike backend APM tracers, which automatically collect spans, mobile tracing requires you to start and stop spans around the specific actions you want to monitor. This approach works independently of Datadog RUM, but can also be used alongside it for deeper visibility into user experiences and backend interactions. - -With Datadog's [Trace SDK for iOS][1] and [Trace SDK for Android][2], you can capture detailed performance data directly from your mobile applications. If you prefer, you can also use [OpenTelemetry for iOS][3] or [OpenTelemetry for Android][4] for custom instrumentation. These tools help you understand app performance, trace requests across services, and optimize both frontend and backend monitoring. +**Note**: When using the Trace SDK independently (without the RUM SDK), backend APM traces do not automatically collect spans, so you need to manually start and stop spans. ## Use cases @@ -98,21 +94,42 @@ The Trace SDK is independent from RUM, so you can track business processes or fl ## Sampling -Sampling in native mobile tracing controls which spans and traces appear in the Datadog UI, helping you balance visibility with data volume. All spans you instrument in your app are recorded and sent to Datadog, but only a subset that are based on your sampling rates and are displayed for analysis. +Sampling in native mobile tracing controls which spans and traces appear in the Datadog UI, helping you balance visibility with data volume. When you manually instrument spans in your app, sampling determines which ones are displayed for analysis in the Datadog interface. + +### Sampling parameters + +The following sampling rate parameters control different aspects of data collection: + +{{< tabs >}} +{{% tab "iOS" %}} + +| Parameter | Description | +|---------------------------------------------|------------------------------------------------------------------| +| `Trace.sampleRate` | Controls the percentage of manually instrumented spans collected by the tracer.| +| `urlSessionTracking.firstPartyHostsTracing.sampleRate` | Controls the percentage of network requests traced for first-party hosts. | +| `RUM.sessionSampleRate` | Controls the percentage of user sessions that are recorded for RUM.| +| `WebViewTracking.logsSampleRate` | Controls the percentage of logs collected from WebViews. | -There are a few sampling rate parameters in the Datadog iOS SDK: +{{% /tab %}} +{{% tab "Android" %}} | Parameter | Description | |---------------------------------------------|------------------------------------------------------------------| -| `Trace.sampleRate` | Controls the percentage of traces (spans) collected by the tracer.| +| `Trace.sampleRate` | Controls the percentage of manually instrumented spans collected by the tracer.| | `urlSessionTracking.firstPartyHostsTracing.sampleRate` | Controls the percentage of network requests traced for first-party hosts. | | `RUM.sessionSampleRate` | Controls the percentage of user sessions that are recorded for RUM.| | `WebViewTracking.logsSampleRate` | Controls the percentage of logs collected from WebViews. | +{{% /tab %}} +{{< /tabs >}} + ### How sampling works -- **Local span sampling** applies to spans you create manually in your app. It's controlled by the `Trace.sampleRate` parameter. For example, if you set this rate to 50, all spans are sent, but only 50% are visible in the UI. Each span event includes the `_dd.agent_psr` field (the sampling rate) and `metrics._sampling_priority_v1` (1 for sampled, 0 for not sampled). -- **Distributed trace sampling** applies to traces that cross service boundaries, such as network requests to your backend. This is controlled by the `urlSessionTracking.firstPartyHostsTracing.sampleRate` parameter. If set to 50, only half of backend requests have the sampled flag set to true, as indicated by the [W3C trace context][7]. All Datadog agents honor this decision, so you see 50% of distributed traces in the UI. +Sampling affects different types of spans you create in your mobile app: + +- **Local span sampling** applies to manually instrumented spans (like business spans or performance profiling spans). It's controlled by the `Trace.sampleRate` parameter. For example, if you set this rate to 50, all manually created spans are sent to Datadog, but only 50% are visible in the UI. Each span event includes the `_dd.agent_psr` field (the sampling rate) and `metrics._sampling_priority_v1` (1 for sampled, 0 for not sampled). + +- **Distributed trace sampling** applies to traces that cross service boundaries, such as network requests to your backend (relevant for the "Wrap a frontend-to-backend distributed trace" use case). This is controlled by the `urlSessionTracking.firstPartyHostsTracing.sampleRate` parameter. If set to 50, only half of backend requests have the sampled flag set to true, as indicated by the [W3C trace context][7]. All Datadog agents honor this decision, so you see 50% of distributed traces in the UI. Sampling rates are applied independently. The most restrictive rate determines what data is visible in the UI for a given session or trace. For example: - If you set a low RUM session sample rate (for example, 1%), only 1% of user sessions are recorded for RUM, but you can still trace all network requests within those sessions by setting the network tracing sample rate to 100%. @@ -125,9 +142,9 @@ To sample 1% of all app sessions and trace all API networks within those session Sampling decisions are communicated through trace headers, ensuring all services in a distributed trace use the same sampling choice. -**Note**: This behavior applies only to iOS SDK `v2.9.0+`. +**Note**: The sampling behavior described above applies to iOS SDK `v2.9.0+` and Android SDK `v1.18.0+`. For earlier versions, see the respective SDK documentation for platform-specific sampling behavior. -## Further Reading +## Further reading {{< partial name="whats-next/whats-next.html" >}} From 1908b945c0029d1ed8e44b15d577bcc6d256682a Mon Sep 17 00:00:00 2001 From: Rosa Trieu <107086888+rtrieu@users.noreply.github.com> Date: Tue, 15 Jul 2025 13:31:51 -0700 Subject: [PATCH 07/11] Apply suggestions from code review Co-authored-by: Pedro Lousada --- .../best-practices-tracing-native-ios-android-apps.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index 1c85dcbcce75f..f333dded920f9 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -55,7 +55,7 @@ Use [OkHttp parent span helpers][1] or [OpenTelemetry addParentSpan][2] to link ### Profiling native application performance -Instrumenting multiple native spans and linking them (using `setActive` on iOS or `addParentSpan` on Android) allows you to profile key parts of your app. This helps you: +Instrumenting multiple native spans and linking them (using `setActive` on iOS or `activateSpan` on Android) allows you to profile key parts of your app. This helps you: - Understand how different methods and components interact - Break down performance bottlenecks - Gain actionable insights into app behavior @@ -105,7 +105,7 @@ The following sampling rate parameters control different aspects of data collect | Parameter | Description | |---------------------------------------------|------------------------------------------------------------------| -| `Trace.sampleRate` | Controls the percentage of manually instrumented spans collected by the tracer.| +| `Trace.Configuration.sampleRate` | Controls the percentage of manually instrumented spans collected by the tracer.| | `urlSessionTracking.firstPartyHostsTracing.sampleRate` | Controls the percentage of network requests traced for first-party hosts. | | `RUM.sessionSampleRate` | Controls the percentage of user sessions that are recorded for RUM.| | `WebViewTracking.logsSampleRate` | Controls the percentage of logs collected from WebViews. | @@ -115,8 +115,8 @@ The following sampling rate parameters control different aspects of data collect | Parameter | Description | |---------------------------------------------|------------------------------------------------------------------| -| `Trace.sampleRate` | Controls the percentage of manually instrumented spans collected by the tracer.| -| `urlSessionTracking.firstPartyHostsTracing.sampleRate` | Controls the percentage of network requests traced for first-party hosts. | +| `AndroidTracer.Builder.setSampleRate` | Controls the percentage of manually instrumented spans collected by the tracer.| +| `DatadogInterceptor.Builder.setTraceSampler` | Controls the percentage of network requests traced for first-party hosts. | | `RUM.sessionSampleRate` | Controls the percentage of user sessions that are recorded for RUM.| | `WebViewTracking.logsSampleRate` | Controls the percentage of logs collected from WebViews. | @@ -129,7 +129,7 @@ Sampling affects different types of spans you create in your mobile app: - **Local span sampling** applies to manually instrumented spans (like business spans or performance profiling spans). It's controlled by the `Trace.sampleRate` parameter. For example, if you set this rate to 50, all manually created spans are sent to Datadog, but only 50% are visible in the UI. Each span event includes the `_dd.agent_psr` field (the sampling rate) and `metrics._sampling_priority_v1` (1 for sampled, 0 for not sampled). -- **Distributed trace sampling** applies to traces that cross service boundaries, such as network requests to your backend (relevant for the "Wrap a frontend-to-backend distributed trace" use case). This is controlled by the `urlSessionTracking.firstPartyHostsTracing.sampleRate` parameter. If set to 50, only half of backend requests have the sampled flag set to true, as indicated by the [W3C trace context][7]. All Datadog agents honor this decision, so you see 50% of distributed traces in the UI. +- **Distributed trace sampling** applies to traces that cross service boundaries, such as network requests to your backend (relevant for the "Wrap a frontend-to-backend distributed trace" use case). This is controlled by the `urlSessionTracking.firstPartyHostsTracing.sampleRate` parameter for iOS and `DatadogInterceptor.Builder.setTraceSampler` parameter for Android. If set to 50, only half of backend requests have the sampled flag set to true, as indicated by the [W3C trace context][7]. All Datadog agents honor this decision, so you see 50% of distributed traces in the UI. Sampling rates are applied independently. The most restrictive rate determines what data is visible in the UI for a given session or trace. For example: - If you set a low RUM session sample rate (for example, 1%), only 1% of user sessions are recorded for RUM, but you can still trace all network requests within those sessions by setting the network tracing sample rate to 100%. From 8661b724b9983b171155dfc8fe6537a3de4ae726 Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Tue, 15 Jul 2025 13:44:19 -0700 Subject: [PATCH 08/11] move other platforms --- ...actices-tracing-native-ios-android-apps.md | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index f333dded920f9..3c7aa49101b30 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -27,6 +27,15 @@ Native mobile tracing gives you precise control over what operations are measure **Note**: When using the Trace SDK independently (without the RUM SDK), backend APM traces do not automatically collect spans, so you need to manually start and stop spans. +This guide focuses on native iOS and Android apps. For other mobile platforms, see the following documentation: + +- [React Native RUM and APM][8] +- [Flutter RUM and APM][9] +- [Kotlin Multiplatform RUM and APM][10] +- [Unity RUM and APM][11] + +For a comprehensive overview of correlating RUM with other telemetry data, see [Correlate RUM with other telemetry data][12]. + ## Use cases ### Wrap a frontend-to-backend distributed trace under a native span @@ -107,8 +116,8 @@ The following sampling rate parameters control different aspects of data collect |---------------------------------------------|------------------------------------------------------------------| | `Trace.Configuration.sampleRate` | Controls the percentage of manually instrumented spans collected by the tracer.| | `urlSessionTracking.firstPartyHostsTracing.sampleRate` | Controls the percentage of network requests traced for first-party hosts. | -| `RUM.sessionSampleRate` | Controls the percentage of user sessions that are recorded for RUM.| -| `WebViewTracking.logsSampleRate` | Controls the percentage of logs collected from WebViews. | + +**Note**: `RUM.sessionSampleRate` controls RUM session sampling and does not affect trace sampling rates. When using the Trace SDK independently of RUM, trace sampling is controlled only by the parameters listed above. {{% /tab %}} {{% tab "Android" %}} @@ -117,8 +126,8 @@ The following sampling rate parameters control different aspects of data collect |---------------------------------------------|------------------------------------------------------------------| | `AndroidTracer.Builder.setSampleRate` | Controls the percentage of manually instrumented spans collected by the tracer.| | `DatadogInterceptor.Builder.setTraceSampler` | Controls the percentage of network requests traced for first-party hosts. | -| `RUM.sessionSampleRate` | Controls the percentage of user sessions that are recorded for RUM.| -| `WebViewTracking.logsSampleRate` | Controls the percentage of logs collected from WebViews. | + +**Note**: `RUM.sessionSampleRate` controls RUM session sampling and does not affect trace sampling rates. When using the Trace SDK independently of RUM, trace sampling is controlled only by the parameters listed above. {{% /tab %}} {{< /tabs >}} @@ -137,8 +146,8 @@ Sampling rates are applied independently. The most restrictive rate determines w **Example scenario:** To sample 1% of all app sessions and trace all API networks within those sessions: -- Set `RUM.sessionSampleRate = 1` -- Set `urlSessionTracking.firstPartyHostsTracing.sampleRate = 100` +- Set `RUM.sessionSampleRate = 1` (controls RUM session sampling only) +- Set `urlSessionTracking.firstPartyHostsTracing.sampleRate = 100` (controls trace sampling for network requests) Sampling decisions are communicated through trace headers, ensuring all services in a distributed trace use the same sampling choice. @@ -155,3 +164,8 @@ Sampling decisions are communicated through trace headers, ensuring all services [5]: https://github.com/DataDog/dd-sdk-ios/blob/develop/DatadogTrace/Sources/TraceConfiguration.swift#L32 [6]: https://github.com/DataDog/dd-sdk-ios/blob/develop/DatadogTrace/Sources/TraceConfiguration.swift#L106 [7]: https://www.w3.org/TR/trace-context/#sampled-flag +[8]: /real_user_monitoring/reactnative/ +[9]: /real_user_monitoring/flutter/ +[10]: /real_user_monitoring/kotlin_multiplatform/ +[11]: /real_user_monitoring/unity/ +[12]: /real_user_monitoring/correlate_with_other_telemetry/apm/ From 99220206a99901d54cb0ccee45db0aead56b9cf7 Mon Sep 17 00:00:00 2001 From: Rosa Trieu <107086888+rtrieu@users.noreply.github.com> Date: Wed, 16 Jul 2025 07:53:47 -0700 Subject: [PATCH 09/11] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maƫl Lilensten --- .../best-practices-tracing-native-ios-android-apps.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index 3c7aa49101b30..401caf6b73f30 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -23,9 +23,9 @@ further_reading: Datadog's Trace SDK for [iOS][1] and [Android][2] lets you add APM spans to your mobile apps. This guide covers usage, key use cases, and sampling rates, with or without using the Datadog RUM SDK. -Native mobile tracing gives you precise control over what operations are measured by manually instrumenting spans in your iOS or Android app code. This approach works independently of Datadog RUM, but can also be used alongside it for deeper visibility into user experiences and backend interactions. You can also use [OpenTelemetry for iOS][3] or [OpenTelemetry for Android][4] for custom instrumentation. +Native mobile tracing gives you precise control over what operations are measured by manually instrumenting spans in your iOS or Android app code. This approach works independently of Datadog RUM, but can also be used alongside it for deeper visibility into user experiences, code level performance, and backend interactions. You can also use [OpenTelemetry for iOS][3] or [OpenTelemetry for Android][4] for custom instrumentation. -**Note**: When using the Trace SDK independently (without the RUM SDK), backend APM traces do not automatically collect spans, so you need to manually start and stop spans. +**Note**: When using the Trace SDK independently (without the RUM SDK), root spans for outgoing network requests do not get automatically created. Therefore, you need to manually start and stop spans on the client side to create frontend-to-backend distributed APM traces. This guide focuses on native iOS and Android apps. For other mobile platforms, see the following documentation: @@ -40,7 +40,7 @@ For a comprehensive overview of correlating RUM with other telemetry data, see [ ### Wrap a frontend-to-backend distributed trace under a native span -You can create distributed traces that span from your mobile frontend to your backend services. This is possible with or without RUM. For example, you can wrap one or more frontend-to-backend traces under a manually created span using the Trace SDK. +You can create distributed traces that span from your mobile frontend to your backend services. The RUM SDK provides an automated way to produce client spans for outgoing network requests. Our Trace SDK provide similar capability, but also allows you to wrap one or more frontend-to-backend traces under more manually created span. {{< tabs >}} {{% tab "iOS" %}} @@ -103,7 +103,7 @@ The Trace SDK is independent from RUM, so you can track business processes or fl ## Sampling -Sampling in native mobile tracing controls which spans and traces appear in the Datadog UI, helping you balance visibility with data volume. When you manually instrument spans in your app, sampling determines which ones are displayed for analysis in the Datadog interface. +Sampling in native mobile tracing controls which spans and traces are ingested in Datadog, helping you balance visibility with data volume. When you manually instrument spans in your app, the ones that are sampled in go trough the APM retention filters which determine which ones end up being displayed for analysis in the Datadog interface. ### Sampling parameters From ba03b920b0dc3697ea0e6ababef588b9502fe1f7 Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Wed, 16 Jul 2025 07:54:41 -0700 Subject: [PATCH 10/11] remove business spans section --- .../guide/best-practices-tracing-native-ios-android-apps.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index 401caf6b73f30..116354b84cb9d 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -97,10 +97,6 @@ See [more Android examples][1]. {{% /tab %}} {{< /tabs >}} -### Creating business spans - -The Trace SDK is independent from RUM, so you can track business processes or flows that span multiple screens or views. For example, you can measure how long it takes users to complete a checkout flow, or how long a background sync takes, regardless of RUM session sampling. These business spans appear in the APM UI and can be used for custom metrics and dashboards. - ## Sampling Sampling in native mobile tracing controls which spans and traces are ingested in Datadog, helping you balance visibility with data volume. When you manually instrument spans in your app, the ones that are sampled in go trough the APM retention filters which determine which ones end up being displayed for analysis in the Datadog interface. From 5387f0824b8729b3a0a2389ee447b3adcb1a874a Mon Sep 17 00:00:00 2001 From: Rosa Trieu Date: Wed, 16 Jul 2025 08:00:10 -0700 Subject: [PATCH 11/11] small errors --- .../guide/best-practices-tracing-native-ios-android-apps.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md index 116354b84cb9d..580817fdd2e4c 100644 --- a/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md +++ b/content/en/real_user_monitoring/guide/best-practices-tracing-native-ios-android-apps.md @@ -40,7 +40,7 @@ For a comprehensive overview of correlating RUM with other telemetry data, see [ ### Wrap a frontend-to-backend distributed trace under a native span -You can create distributed traces that span from your mobile frontend to your backend services. The RUM SDK provides an automated way to produce client spans for outgoing network requests. Our Trace SDK provide similar capability, but also allows you to wrap one or more frontend-to-backend traces under more manually created span. +You can create distributed traces that span from your mobile frontend to your backend services. The RUM SDK provides an automated way to produce client spans for outgoing network requests. Datadog's Trace SDK provides similar capability, but also allows you to wrap one or more frontend-to-backend traces under manually created spans. {{< tabs >}} {{% tab "iOS" %}} @@ -99,7 +99,7 @@ See [more Android examples][1]. ## Sampling -Sampling in native mobile tracing controls which spans and traces are ingested in Datadog, helping you balance visibility with data volume. When you manually instrument spans in your app, the ones that are sampled in go trough the APM retention filters which determine which ones end up being displayed for analysis in the Datadog interface. +Sampling in native mobile tracing controls which spans and traces are ingested in Datadog, helping you balance visibility with data volume. When you manually instrument spans in your app, the ones that are sampled in go through the APM retention filters which determine which ones end up being displayed for analysis in the Datadog interface. ### Sampling parameters @@ -141,7 +141,7 @@ Sampling rates are applied independently. The most restrictive rate determines w - If you set a high trace sample rate but a low RUM sample rate, you may see traces without corresponding RUM data. **Example scenario:** -To sample 1% of all app sessions and trace all API networks within those sessions: +To sample 1% of all app sessions and trace all API network requests within those sessions: - Set `RUM.sessionSampleRate = 1` (controls RUM session sampling only) - Set `urlSessionTracking.firstPartyHostsTracing.sampleRate = 100` (controls trace sampling for network requests)