diff --git a/en/rum/sdk/flutter/advanced-config.mdx b/en/rum/sdk/flutter/advanced-config.mdx index 93f4d0e0..5fefd177 100644 --- a/en/rum/sdk/flutter/advanced-config.mdx +++ b/en/rum/sdk/flutter/advanced-config.mdx @@ -4,41 +4,71 @@ description: "Configure sampling, tracking consent, event filtering, distributed keywords: ["RUM", "Flutter SDK", "advanced configuration", "sampling", "tracking consent", "symbol upload"] --- -This page describes the advanced configuration options of the Flutter SDK. All configuration is passed through `DatadogConfiguration` and `DatadogRumConfiguration`. +This page covers the Flutter SDK's advanced options. Configuration is split across two objects: `DatadogConfiguration` carries SDK-level settings (credentials, site, version, upload strategy), and `DatadogRumConfiguration` carries RUM feature settings (sampling, automatic collection toggles, event mappers). -## Sampling rate +## Sampling rates ```dart DatadogRumConfiguration( applicationId: '', - sessionSamplingRate: 100.0, // Session sampling rate - traceSampleRate: 20.0, // Trace sampling rate on resources + sessionSamplingRate: 100.0, // session sampling rate + traceSampleRate: 20.0, // tracing sampling rate on resources ); ``` +Both `sessionSamplingRate` and `traceSampleRate` are clamped to the `0`–`100` range. Passing a value outside that range does not raise an error — it is truncated. + +## Application version and service name + +`version`, `service`, and `flavor` determine how RUM events are attributed, and whether crash stack traces can be matched against your symbol files. + +```dart +DatadogConfiguration( + clientToken: '', + env: 'production', + site: FlashcatSite.cn, + service: 'com.example.shopping', + version: '1.4.2', + flavor: 'release', + rumConfiguration: DatadogRumConfiguration(applicationId: ''), +); +``` + +| Field | Type | Default | Description | +|------|------|--------|------| +| `service` | string | Falls back to the native SDK's default when unset | Service name, used to distinguish applications in the console. It must match the value used when uploading symbol files | +| `version` | string | The version in `pubspec.yaml`, minus any build or pre-release suffix | Application version. Set it explicitly when you need the full version string, or when the pubspec version differs from your released version | +| `flavor` | string | `null` | Application variant (for example, per-channel builds). When `null`, it is not written to RUM as a tag, but symbol upload tools treat it as `release` by default | + + +`version` is a Datadog-style tag and cannot contain `+`. The SDK replaces `+` with `-` before reporting — for example, `1.4.2+18` becomes `1.4.2-18`. Use the replaced value when uploading symbol files, otherwise stack traces cannot be resolved. + + ## Tracking consent -`TrackingConsent` controls whether data is collected and reported, to meet compliance requirements such as GDPR: +`TrackingConsent` controls whether data is collected and reported, so you can meet requirements such as GDPR: | Value | Behavior | |------|------| | `TrackingConsent.granted` | Collect and report | | `TrackingConsent.notGranted` | Do not collect | -| `TrackingConsent.pending` | Cache first, then decide whether to report or drop after the user grants consent | +| `TrackingConsent.pending` | Cache first, then report or discard once the user decides | ```dart -// Pass in during initialization +// Pass it during initialization await DatadogSdk.runApp(configuration, TrackingConsent.pending, () async { runApp(const MyApp()); }); -// Update after the user grants consent +// Update it after the user grants consent DatadogSdk.instance.setTrackingConsent(TrackingConsent.granted); ``` +If a user withdraws consent, call `DatadogSdk.instance.clearAllData()` to discard the locally cached data that has not been reported yet. + ## Event filtering and masking -Event mappers run before events are reported; return `null` to drop the event, or return it after modification. You can use them to mask sensitive fields, remove noise, or rename views. +Event mappers run before an event is reported. Return `null` to drop the event, or return it after modification. Use them to mask sensitive fields, remove noise, or rename views. ```dart DatadogRumConfiguration( @@ -46,7 +76,7 @@ DatadogRumConfiguration( viewEventMapper: (event) => event, actionEventMapper: (event) => event, resourceEventMapper: (event) { - // For example, remove the query token from the URL + // For example, strip a query token from the URL return event; }, errorEventMapper: (event) => event, @@ -54,9 +84,13 @@ DatadogRumConfiguration( ); ``` + +`viewEventMapper` must return an event and cannot drop views; the other mappers can return `null` to drop their event. Mappers can only modify mutable (non-`final`) properties on an event. + + ## Distributed tracing -For hosts that match `firstPartyHosts`, the SDK injects the W3C `traceparent` to correlate frontend RUM with backend APM. Tracing requires network collection (`enableHttpTracking()`). +For hosts matched by `firstPartyHosts`, the SDK injects tracing headers so you can correlate frontend RUM with backend APM. Tracing requires network collection (`enableHttpTracking()` or `DatadogClient`). ```dart DatadogConfiguration( @@ -71,9 +105,44 @@ DatadogConfiguration( )..enableHttpTracking(); ``` -## Custom reporting endpoint +### Choose tracing header types -For on-premises deployments, override the default reporting endpoint through `customEndpoint`: +`firstPartyHosts` is a shorthand: every host you list receives both the Datadog-style `x-datadog-*` headers and the W3C `traceparent` header. If your backend accepts only one of them, or different gateways use different protocols, use `firstPartyHostsWithTracingHeaders` to specify them per host: + +```dart +DatadogConfiguration( + clientToken: '', + env: 'production', + site: FlashcatSite.cn, + firstPartyHostsWithTracingHeaders: { + 'api.example.com': {TracingHeaderType.tracecontext}, + 'legacy.example.com': {TracingHeaderType.b3multi}, + }, + rumConfiguration: DatadogRumConfiguration(applicationId: ''), +); +``` + +| `TracingHeaderType` | Injected headers | +|------|------| +| `datadog` | `x-datadog-trace-id`, `x-datadog-parent-id`, `x-datadog-sampling-priority`, and others | +| `tracecontext` | W3C `traceparent` / `tracestate` | +| `b3` | OpenTelemetry B3 single header (`b3`) | +| `b3multi` | OpenTelemetry B3 multiple headers (`X-B3-TraceId` and others) | + +You can pass `firstPartyHosts` and `firstPartyHostsWithTracingHeaders` together; the SDK takes the union of the two. + +### Control when headers are injected + +`traceContextInjection` decides whether unsampled requests still carry tracing headers: + +| Value | Behavior | +|------|------| +| `TraceContextInjection.sampled` (default) | Inject tracing headers only into sampled requests | +| `TraceContextInjection.all` | Inject tracing headers into every request and let the backend decide how to handle unsampled traces | + +## Custom intake endpoint + +For on-premises deployments, override the default intake endpoint through `customEndpoint`: ```dart DatadogRumConfiguration( @@ -82,33 +151,64 @@ DatadogRumConfiguration( ); ``` +## Collection in background isolates + +If you run network requests or business logic in a background isolate, attach to the already-initialized SDK inside that isolate so its events land in the same session: + +```dart +await DatadogSdk.instance.attachToBackgroundIsolate(); +``` + + +The SDK must already be initialized on the main isolate for `attachToBackgroundIsolate()` to receive a configuration. Calling it before initialization completes, or on a platform without isolate support, logs a warning and is silently skipped. + + ## Symbol file upload -To resolve crash and error stacks back to source locations, you need to upload symbol files. A Flutter application may contain both Dart and native frames: +To resolve crash and error stack traces back to source locations, upload symbol files. A Flutter application can contain both Dart and native frames: -| Frame type | Required files | How to generate | +| Frame type | Required file | How it is produced | |----------|----------|----------| | Dart | Flutter symbols | `flutter build --split-debug-info= --obfuscate` | -| iOS Native | dSYM | Xcode build output | -| Android Native | mapping files | R8 / ProGuard output | +| iOS native | dSYM | Xcode build output | +| Android native | mapping file | R8 / ProGuard output | -Use the FlashCat CLI to upload symbol files: +Upload symbol files with the FlashCat CLI: ```bash -# Example: upload the symbol files for the corresponding version +# Example: upload the symbol files for a given version flashcat-cli flutter-symbols upload --service --version ``` -The `version` and `service` used at upload time must exactly match the values in the SDK initialization. Otherwise the console can receive crash events but cannot resolve stack frames back to source locations. Make symbol upload part of your release build process. +The `version` and `service` used at upload must exactly match the values passed during SDK initialization. Otherwise the console receives crash events but cannot resolve frames back to source locations. Make symbol upload part of your release build pipeline. -## Other configuration - -| Configuration | Default | Description | -|------|--------|------| -| `nativeCrashReportEnabled` | false | Whether to collect native crashes | -| `detectLongTasks` | true | Whether to collect long tasks | -| `longTaskThreshold` | 0.1s | Long task threshold | -| `trackBackgroundEvents` | false | Whether to collect events while the application is in the background | -| `batchSize` / `uploadFrequency` | — | Upload batch size and frequency, balancing real-time delivery against battery usage | +## RUM collection options + +Set all of the following on `DatadogRumConfiguration`. + +| Option | Type | Default | Description | +|------|------|--------|------| +| `detectLongTasks` | bool | `true` | Whether to collect long tasks | +| `longTaskThreshold` | double | `0.1` (seconds) | Long task threshold, with a minimum of 0.02. Smaller values are raised to 0.02 | +| `trackFrustrations` | bool | `true` | Whether to generate frustration signals from user actions | +| `trackBackgroundEvents` | bool | `false` | Whether to collect events while no view is active, including while the application is in the background. When enabled, these events attach to an automatically created background view, which can create additional sessions and affect billing | +| `trackAnonymousUser` | bool | `true` | Whether to generate an anonymous user ID that persists across launches, correlating sessions from the same device without collecting personal data | +| `vitalUpdateFrequency` | `VitalsFrequency?` | `average` | Mobile vitals collection frequency: `frequent` (100ms), `average` (500ms), `rare` (1000ms). Set to `null` to disable vitals collection | +| `reportFlutterPerformance` | bool | `false` | Whether to report Flutter-specific build and raster times, collected through `SchedulerBinding.addTimingsCallback` | +| `initialResourceThreshold` | double | `0.1` (seconds) | How long after a view starts a resource can begin and still count toward Time to Network-Settled (TNS) | +| `trackNonFatalAnrs` | `bool?` | Platform-dependent | Whether to report non-fatal Android ANRs. Disabled by default on Android 30+ (too noisy), enabled by default on Android 29 and below (where fatal ANRs cannot be reported) | +| `appHangThreshold` | `double?` | `null` (disabled) | iOS app hang threshold, in seconds. For example, `0.25` reports hangs lasting at least 250ms | +| `telemetrySampleRate` | double | `20.0` | Sampling rate for the SDK's own telemetry | + +## Upload strategy + +Set all of the following on `DatadogConfiguration` to trade off data freshness against device resource usage. All three default to `null`, which keeps the native SDK's default strategy. + +| Option | Type | Values | Description | +|------|------|------|------| +| `batchSize` | `BatchSize?` | `small` / `medium` / `large` | Preferred size of a single batch. Smaller batches upload more promptly but issue more requests | +| `uploadFrequency` | `UploadFrequency?` | `frequent` / `average` / `rare` | How often the SDK attempts to upload | +| `batchProcessingLevel` | `BatchProcessingLevel?` | `low` / `medium` / `high` | How many batches are processed sequentially in one read/upload cycle. `high` sends more data per cycle but uses more CPU and memory; `low` does the opposite. The native default is `medium` | +| `nativeCrashReportEnabled` | bool | `false` | Whether to collect native iOS / Android crashes | diff --git a/en/rum/sdk/flutter/compatible.mdx b/en/rum/sdk/flutter/compatible.mdx index a0871428..f3c7774d 100644 --- a/en/rum/sdk/flutter/compatible.mdx +++ b/en/rum/sdk/flutter/compatible.mdx @@ -4,66 +4,76 @@ description: "Review the platforms, Flutter versions, companion packages, and cu keywords: ["RUM", "Flutter SDK", "compatibility", "Dart", "iOS", "Android"] --- -This page describes the Flutter SDK support scope and current limits so you can determine whether your project meets the requirements before integration. +This page describes the Flutter SDK's supported scope and current limitations, so you can tell whether your project meets the requirements before integrating. -## Support scope +## Supported scope | Item | Support | |------|----------| -| SDK version | `flashcat_flutter_plugin` 0.1.0 | -| Target platforms | **iOS and Android** (Flutter Web / Desktop not supported) | -| Flutter / Dart | Flutter ≥ 3.0, Dart ≥ 3.0 | -| iOS | Deployment target ≥ 12.0 | -| Android | `minSdkVersion` ≥ 21 | -| RUM data source | Events always write `source: "flutter"` | +| SDK version | `flashcat_flutter_plugin` 0.1.1 | +| Target platforms | **iOS and Android** (Flutter Web and Desktop are not supported) | +| Flutter / Dart | Flutter ≥ 3.27.0, Dart SDK ≥ 3.6.0 | +| iOS | Deployment target ≥ 13.0, `use_frameworks!` required in the Podfile | +| Android | `minSdkVersion` ≥ 23; Kotlin ≥ 2.1.0 when using Kotlin | +| Native SDK dependencies | iOS 0.5.0 (`Flashcat*` pods), Android 0.4.1 (`cloud.flashcat:*`) | +| RUM data source | Events always carry `source: "flutter"` | | Implementation | A Flutter plugin wrapping the native iOS / Android SDKs | -| Data upload | `POST /api/v2/rum` | +| Data intake | `POST /api/v2/rum` | ## Packages and capabilities -| Package | pub name | Description | -|------|------|------| -| RUM / Core / Crash | `flashcat_flutter_plugin` | Initialization, configuration, RUM (view / action / resource / error / session), and native crash collection | -| HTTP tracking | `datadog_tracking_http_client` | Automatically records `dart:io` / `http` requests as resources and injects trace headers (requires `dependency_overrides`, not v1 core) | -| WebView tracking | `flashcat_webview_tracking` | Correlates RUM data inside WebViews | +All three packages are published on pub.dev under the verified publisher `flashcat.cloud`. + +| Capability | pub package | Version | Description | +|------|------|------|------| +| RUM / Core / crash | `flashcat_flutter_plugin` | 0.1.1 | Initialization, configuration, RUM (view / action / resource / error / session), native crash reporting | +| HTTP tracking | `flashcat_tracking_http_client` | 0.1.0 | Records `dart:io` / `http` requests as resources and injects tracing headers through `enableHttpTracking()`; also provides `DatadogClient` for finer control | +| WebView tracking | `flashcat_webview_tracking` | 0.1.0 | Correlates RUM data from inside a WebView through `trackDatadogEvents` | + + +Both companion packages depend on `flashcat_flutter_plugin: ^0.1.0` and resolve alongside the main package without any `dependency_overrides`. + -The Dart class names still follow the upstream `Datadog*` naming; only the site enum `FlashcatSite` (`.cn` default / `.staging`) and the package name are rebranded. The `DatadogSdk`, `DatadogConfiguration`, `DatadogRumConfiguration`, `DatadogNavigationObserver`, and other classes in the documentation examples are the actual exported class names. +The Dart class names still follow the upstream `Datadog*` naming; only the package names and the site enum `FlashcatSite` are rebranded. `DatadogSdk`, `DatadogConfiguration`, `DatadogRumConfiguration`, `DatadogNavigationObserver`, and `DatadogClient` in these examples are the actual exported class names. `FlashcatSite` has two values, `.cn` (production) and `.staging` (internal use); `site` is a required parameter of `DatadogConfiguration` and must be passed explicitly. ## Supported automatic collection | Capability | Support | Description | |------|----------|------| -| Automatic views | Supported | Requires a `DatadogNavigationObserver` on `MaterialApp` | -| Automatic actions | Supported | Requires wrapping the subtree with `RumUserActionDetector`; `trackFrustrations` is enabled by default | -| Automatic resources | Supported (requires companion package) | Through `enableHttpTracking()` from `datadog_tracking_http_client` | -| Unhandled exceptions | Supported | When using `DatadogSdk.runApp`, automatically takes over `FlutterError.onError` / `PlatformDispatcher.onError` | +| Automatic views | Supported | Add `DatadogNavigationObserver` to your `MaterialApp` | +| Automatic actions | Supported | Wrap your subtree with `RumUserActionDetector`; `trackFrustrations` is on by default | +| Automatic resources | Supported (companion package) | Through `enableHttpTracking()` from `flashcat_tracking_http_client` | +| WebView events | Supported (companion package) | Through `trackDatadogEvents` from `flashcat_webview_tracking` | +| Unhandled exceptions | Supported | `DatadogSdk.runApp` takes over `FlutterError.onError` / `PlatformDispatcher.onError` | | Native crashes | Supported | Requires `nativeCrashReportEnabled: true` | -| Distributed tracing | Supported | Injects W3C `traceparent` for hosts that match `firstPartyHosts` | +| Mobile vitals | Supported | `vitalUpdateFrequency` defaults to `VitalsFrequency.average` (500ms) | +| Android ANRs | Supported | Enable non-fatal ANR reporting through `trackNonFatalAnrs` | +| iOS app hangs | Supported | Set the hang threshold through `appHangThreshold` | +| Distributed tracing | Supported | Injects Datadog-style and W3C `traceparent` headers for hosts matched by `firstPartyHosts` | +| Background isolates | Supported | Reuse the initialized SDK in a background isolate through `attachToBackgroundIsolate()` | -## Current limits +## Current limitations -| Limit | Description | +| Limitation | Description | |------|------| | Platform scope | iOS / Android only; Flutter Web and Desktop are not supported | -| Logs | v1 does not support log reporting (`DatadogLoggingConfiguration` is a no-op) | -| Session Replay | Not supported in v1 (`datadog_session_replay` is a preview, not in the core scope) | -| Companion package naming | `datadog_tracking_http_client` / `datadog_session_replay` still declare their dependency on `datadog_flutter_plugin: ^3.0.0`, so integrating this fork requires `dependency_overrides` | -| dio / gql / grpc | The corresponding interceptor packages are not yet adapted to this fork in v1 | -| Page performance metrics | `reportFlutterPerformance` is disabled by default; the console performance page is currently hidden for Flutter to avoid showing zero-value empty data | -| pub.dev publication | Official publication is being confirmed; git dependencies are currently recommended | +| Logs | Log reporting is not supported. A `loggingConfiguration` you pass is cleared during initialization with a warning — the API compiles but sends nothing | +| Session Replay | Not supported. The `datadog_session_replay` package in the repository is still the upstream Datadog package and has not been rebranded | +| dio / gql / grpc | The corresponding interceptor packages still point at the upstream `datadog_flutter_plugin` and are not yet adapted to this fork | +| Page performance metrics | `reportFlutterPerformance` is off by default; the console's performance page is currently hidden for Flutter to avoid showing empty zero values | -## Symbolication compatibility +## Symbol resolution compatibility -Flutter crash stacks can contain both Dart frames and native (iOS / Android) frames. To resolve stack frames back to source locations, you need to upload the corresponding symbol files: +A Flutter crash stack can contain both Dart frames and native (iOS / Android) frames. To resolve frames back to source locations, upload the matching symbol files: -| Frame type | Required uploaded files | +| Frame type | Required upload | |----------|--------------| -| Dart | Flutter symbols (`flutter build --split-debug-info` output) | -| iOS Native | dSYM | -| Android Native | mapping files | +| Dart | Flutter symbols (output of `flutter build --split-debug-info`) | +| iOS native | dSYM | +| Android native | mapping file | -Symbol files are uploaded through the FlashCat CLI, and the `version` used at upload time must match the `version` in the SDK initialization. Otherwise the console can receive crash events but cannot resolve the stacks. +Upload symbol files with the FlashCat CLI, and make sure the `version` used at upload matches the `version` passed during SDK initialization. Otherwise the console receives crash events but cannot resolve the stack traces. diff --git a/en/rum/sdk/flutter/data-collection.mdx b/en/rum/sdk/flutter/data-collection.mdx index 3fb8f68d..13d3e82a 100644 --- a/en/rum/sdk/flutter/data-collection.mdx +++ b/en/rum/sdk/flutter/data-collection.mdx @@ -12,10 +12,14 @@ This page describes which data the Flutter SDK collects, how it is uploaded, and |------|----------|------| | view | Route change (`DatadogNavigationObserver`) or manual API | One page visit, recording load time and the number of internal actions / resources / errors | | action | Automatic recognition by `RumUserActionDetector` or `rum.addAction` | User interaction (tap / scroll / swipe / custom), can correlate frustration signals | -| resource | `enableHttpTracking()` or `DatadogClient` | One network request, recording URL, method, status code, duration, and size | +| resource | `enableHttpTracking()` from `flashcat_tracking_http_client`, or `DatadogClient` | One network request, recording URL, method, status code, duration, and size | | error | Automatic (unhandled exceptions / native crashes) or `rum.addError` | Errors and crashes, including type, message, and stack | | long task | `detectLongTasks` enabled by default | Main-thread blocking that exceeds `longTaskThreshold` (default 0.1s) | +Events produced inside a WebView are bridged by `flashcat_webview_tracking` and merged into the same Flutter session as the event types above, so you do not need to treat them separately. + +Mobile vitals (CPU, memory, frame rate) are not standalone events. They are sampled at the `vitalUpdateFrequency` interval and attached to view events. + ## Automatically collected context Each event automatically carries the following context (collected by the native layer): @@ -24,7 +28,9 @@ Each event automatically carries the following context (collected by the native - **Device information**: device model, operating system and version, screen size - **Session information**: `session.id`, sampled by `sessionSamplingRate` - **Connection information**: network type (when available) -- **User information**: `usr.id` / `usr.name` / `usr.email` set through `setUserInfo` +- **User information**: `usr.id` / `usr.name` / `usr.email` set through `setUserInfo`, plus any custom attributes appended with `addUserExtraInfo` +- **Account information**: `account.id` / `account.name` set through `setAccountInfo`, plus its custom attributes +- **Anonymous user ID**: generated when `trackAnonymousUser` is enabled (the default), persisted across launches to correlate signed-out sessions from the same device ## Manual instrumentation @@ -45,6 +51,9 @@ rum?.addErrorInfo('payment failed', RumErrorSource.source); // Attach a global attribute (written to all subsequent events) rum?.addAttribute('tenant', 'acme'); + +// End the current session; the next interaction starts a new one +rum?.stopSession(); ``` ## Sampling and control diff --git a/en/rum/sdk/flutter/sdk-integration.mdx b/en/rum/sdk/flutter/sdk-integration.mdx index a39e8171..c30b2748 100644 --- a/en/rum/sdk/flutter/sdk-integration.mdx +++ b/en/rum/sdk/flutter/sdk-integration.mdx @@ -7,7 +7,7 @@ keywords: ["RUM", "Flutter SDK", "Dart", "user monitoring", "mobile monitoring"] The Flutter SDK wraps the native iOS / Android SDKs and provides RUM capabilities through `flashcat_flutter_plugin`. After initialization, the SDK reports the application's views, user actions, network requests, errors, and crashes to Flashduty RUM, with `source: "flutter"` identifying the data source. -The current SDK version is `0.1.0` and supports only the **iOS and Android** platforms (Flutter Web is not supported). The Dart class names still follow the upstream `Datadog*` naming (such as `DatadogSdk` and `DatadogConfiguration`); only the package name `flashcat_flutter_plugin` and the site enum `FlashcatSite` are rebranded. v1 does not yet include Logs, Session Replay, or the dio / gql / grpc companion packages. +The current SDK version is `flashcat_flutter_plugin` 0.1.1, and it supports only the **iOS and Android** platforms (Flutter Web and Desktop are not supported). The Dart class names still follow the upstream `Datadog*` naming (such as `DatadogSdk` and `DatadogConfiguration`); only the package names and the site enum `FlashcatSite` are rebranded. v1 does not yet include Logs or Session Replay. ## Prerequisites @@ -16,28 +16,32 @@ Before integrating the SDK, complete these steps: - Create or select a RUM application in the Flashduty console, then obtain the **Application ID** and **Client Token** - Make sure your application can reach `https://browser.flashcat.cloud/api/v2/rum` -- Flutter SDK ≥ 3.0, Dart ≥ 3.0; iOS deployment target ≥ 12.0, Android `minSdkVersion` ≥ 21 +- Flutter ≥ 3.27.0, Dart SDK ≥ 3.6.0 +- iOS deployment target ≥ 13.0, with `use_frameworks!` enabled in your Podfile (enabled by default in Flutter) +- Android `minSdkVersion` ≥ 23; if you use Kotlin, its version must be ≥ 2.1.0 - Initialize the SDK early in application startup (in `main()`) ## Install the SDK -Add `flashcat_flutter_plugin` to `pubspec.yaml`, then run `flutter pub get`. - - -The pub.dev publication of `flashcat_flutter_plugin` is still being confirmed. To keep the dependency resolvable, the example below uses a git source. Once it is officially published to pub.dev, you can switch to the hosted form `flashcat_flutter_plugin: ^0.1.0`. - +All three packages are published on pub.dev under the verified publisher `flashcat.cloud`. Add the ones you need to `pubspec.yaml`, then run `flutter pub get`. ```yaml pubspec.yaml dependencies: - flashcat_flutter_plugin: - git: - url: https://github.com/flashcatcloud/fc-sdk-flutter - path: packages/datadog_flutter_plugin + # RUM / Core / crash reporting, required + flashcat_flutter_plugin: ^0.1.1 + # Automatic network collection and distributed tracing, optional + flashcat_tracking_http_client: ^0.1.0 + # WebView data correlation, optional + flashcat_webview_tracking: ^0.1.0 ``` + +Both companion packages depend on `flashcat_flutter_plugin: ^0.1.0`, so they resolve alongside the main package without any `dependency_overrides`. + + ## Initialize the SDK -We recommend initializing in `main()`, before `runApp`. When you start the application with `DatadogSdk.runApp`, the SDK automatically takes over `FlutterError.onError` and `PlatformDispatcher.instance.onError`, so it can collect unhandled exceptions without manual wiring. +Initialize in `main()` before `runApp`. When you start your application with `DatadogSdk.runApp`, the SDK takes over `FlutterError.onError` and `PlatformDispatcher.instance.onError`, so unhandled exceptions are collected without any manual wiring. ```dart main.dart import 'package:flutter/widgets.dart'; @@ -47,14 +51,15 @@ Future main() async { final configuration = DatadogConfiguration( clientToken: '', env: 'production', - service: 'com.example.shopping', site: FlashcatSite.cn, - nativeCrashReportEnabled: true, // Collect native iOS / Android crashes - firstPartyHosts: ['api.example.com'], // Inject distributed trace headers for these hosts + service: 'com.example.shopping', + version: '1.4.2', // must match the version used when uploading symbol files + nativeCrashReportEnabled: true, // collect native iOS / Android crashes + firstPartyHosts: ['api.example.com'], // inject distributed tracing headers for these hosts rumConfiguration: DatadogRumConfiguration( applicationId: '', sessionSamplingRate: 100.0, - // customEndpoint: 'https://your-ingest.example.com', // Custom reporting endpoint for on-premises deployments + // customEndpoint: 'https://your-ingest.example.com', // custom intake for private deployments ), ); @@ -64,11 +69,13 @@ Future main() async { } ``` +`clientToken`, `env`, and `site` are required parameters. `site` has no implicit default, so pass `FlashcatSite.cn` explicitly in production. + -Do not use server-side secrets in client code. `clientToken` is only for client-side RUM reporting, and `applicationId` assigns events to the RUM application. +Never use a server-side key in client code. `clientToken` is only for client-side RUM reporting, and `applicationId` attributes the data to a RUM application. -If you need to control the startup flow yourself, outside of `runApp`, you can also initialize manually, but you must wire up error collection yourself: +If you need to control startup yourself instead of using `runApp`, you can initialize manually, but you must wire up error collection on your own: ```dart WidgetsFlutterBinding.ensureInitialized(); @@ -81,9 +88,9 @@ FlutterError.onError = (details) { }; ``` -## Track views +## Collect page views -Add a `DatadogNavigationObserver` to your `MaterialApp` (or `CupertinoApp`), and the SDK automatically records the Navigator's route changes as RUM views. +Add `DatadogNavigationObserver` to your `MaterialApp` (or `CupertinoApp`), and the SDK records Navigator route changes as RUM views automatically. ```dart import 'package:flashcat_flutter_plugin/flashcat_flutter_plugin.dart'; @@ -97,31 +104,33 @@ MaterialApp( ``` -The `DatadogNavigationObserver` constructor uses the named parameter `datadogSdk:`. By default it uses the route's `settings.name` as the view name; you can customize the view name or filter routes through the `viewInfoExtractor` callback. +The `DatadogNavigationObserver` constructor uses the named parameter `datadogSdk:`. It uses the route's `settings.name` as the view name by default; use the `viewInfoExtractor` callback to customize view names or filter routes. -For scenarios that do not use named routes, you can use `DatadogNavigationObserverProvider` together with `DatadogRouteAwareMixin` to manage views manually. +If you do not use named routes, combine `DatadogNavigationObserverProvider` with `DatadogRouteAwareMixin` to manage views manually. -## Track user actions +## Collect user actions -In the RUM configuration, `trackFrustrations` is enabled by default. After you wrap your application subtree with `RumUserActionDetector`, the SDK automatically recognizes interactions such as taps and generates action events; you can also record actions manually. +`trackFrustrations` is enabled by default in the RUM configuration. Wrap your widget subtree with `RumUserActionDetector`, and the SDK detects interactions such as taps and generates action events. You can also record actions manually. ```dart -// Automatically recognize user interactions in the subtree +// Automatically detect user interactions within the subtree RumUserActionDetector( rum: DatadogSdk.instance.rum, child: const MyApp(), ); -// Manually record one action +// Record one action manually DatadogSdk.instance.rum?.addAction(RumActionType.tap, 'Checkout'); ``` -## Track network requests +## Collect network requests -Automatic network collection is provided by the separate `datadog_tracking_http_client` package and enabled through the `enableHttpTracking()` extension method on the configuration object. It globally replaces `HttpClient`, records `dart:io` / `http` requests as RUM resources, and injects W3C trace headers for hosts that match `firstPartyHosts`. +Automatic network collection is provided by `flashcat_tracking_http_client` and enabled through the `enableHttpTracking()` extension method on the configuration object. It replaces `HttpClient` globally, records `dart:io` / `http` requests as RUM resources, and injects tracing headers for hosts matched by `firstPartyHosts`. ```dart +import 'package:flashcat_tracking_http_client/flashcat_tracking_http_client.dart'; + final configuration = DatadogConfiguration( clientToken: '', env: 'production', @@ -132,12 +141,58 @@ final configuration = DatadogConfiguration( ``` -`datadog_tracking_http_client` currently declares its dependency on `datadog_flutter_plugin` (`^3.0.0`), which cannot be resolved directly with this fork's `flashcat_flutter_plugin` 0.1.0. When you enable network collection, add a `dependency_overrides` entry in `pubspec.yaml` pointing to this fork. This capability is not part of the v1 core scope and can be integrated as needed. +`enableHttpTracking()` modifies `HttpOverrides.global`. If your application also needs custom `HttpOverrides`, set them up **before** initializing the SDK — during initialization the SDK reads `HttpOverrides.current` and creates its client on top of it. + + +### Use DatadogClient for finer control + +If you only want to track specific requests, or you use native HTTP implementations such as `cronet_http` or `cupertino_http` (which the global replacement does not cover), wrap the `http` package's `Client` with `DatadogClient` instead: + +```dart +import 'package:flashcat_tracking_http_client/flashcat_tracking_http_client.dart'; +import 'package:http/http.dart' as http; + +final datadogClient = DatadogClient( + datadogSdk: DatadogSdk.instance, + innerClient: http.Client(), // optional; a default Client is created if omitted +); +``` + +You still need to declare `firstPartyHosts` in the configuration to enable distributed tracing with `DatadogClient`. Outside of the `cronet_http` / `cupertino_http` cases, avoid enabling `enableHttpTracking()` and `DatadogClient` at the same time — they interfere with each other. + +## Collect WebView data + +In hybrid applications, `flashcat_webview_tracking` bridges RUM events produced inside a WebView into the Flutter session, so the WebView does not become a monitoring blind spot. Use it together with [`webview_flutter`](https://pub.dev/packages/webview_flutter). + +```yaml pubspec.yaml +dependencies: + webview_flutter: ^4.0.4 + flashcat_flutter_plugin: ^0.1.1 + flashcat_webview_tracking: ^0.1.0 +``` + +Call the `trackDatadogEvents` extension method on `WebViewController` and pass the list of hosts allowed to bridge events: + +```dart +import 'package:flashcat_flutter_plugin/flashcat_flutter_plugin.dart'; +import 'package:flashcat_webview_tracking/flashcat_webview_tracking.dart'; + +final webViewController = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..trackDatadogEvents( + DatadogSdk.instance, + ['myapp.example'], // allowed hosts; events from other origins are ignored + ) + ..loadRequest(Uri.parse('https://myapp.example')); +``` + + +On Android you must set `JavaScriptMode.unrestricted`. Otherwise the bridge script cannot be injected and WebView events are not reported. -## Identify users +## Attach user information -After sign-in, you can set the current user. The SDK writes the user fields to the `usr` object on subsequent RUM events. +After a user logs in, set the current user. The SDK writes the user fields into the `usr` object of subsequent RUM events. `id` is required. ```dart DatadogSdk.instance.setUserInfo( @@ -145,17 +200,56 @@ DatadogSdk.instance.setUserInfo( name: 'Alice', email: 'alice@example.com', ); + +// Append custom user attributes, merged with existing ones; set an attribute to null to remove it +DatadogSdk.instance.addUserExtraInfo({'plan': 'pro', 'trial': null}); +``` + +Clear the user information when the user logs out: + +```dart +DatadogSdk.instance.clearUserInfo(); +``` + + +Use `clearUserInfo()` to clear user information. The `id` parameter of `setUserInfo` is a required named parameter, so an empty `setUserInfo()` call does not compile. + + +`clearUserInfo()` also empties the `usr` attribute on the active session and the active view. To keep the user information already attached to them, end the session or view first with `rum.stopSession()` or `rum.stopView()`, then clear. + +## Attach account information + +Applications serving business customers can attribute data by the account a user belongs to (tenant, organization, or team). Account information is written into the `account` object of subsequent events, independently of user information. + +```dart +DatadogSdk.instance.setAccountInfo( + id: 'acct-2048', + name: 'ACME Inc.', + extraInfo: {'tier': 'enterprise'}, +); + +// Append custom account attributes +DatadogSdk.instance.addAccountExtraInfo({'region': 'cn-north'}); + +// Clear when switching or leaving an account +DatadogSdk.instance.clearAccountInfo(); ``` -Clear user information when the user signs out: +As with `clearUserInfo()`, `clearAccountInfo()` empties the `account` attribute on the active session and the active view. + +## Clear locally cached data + +If a user withdraws consent, or you need to honor a data deletion request, discard the local data that has not been reported yet: ```dart -DatadogSdk.instance.setUserInfo(); +DatadogSdk.instance.clearAllData(); ``` +This method only clears cached data that has not been sent to the server. Data already reported is unaffected. + ## Report errors -When you use `DatadogSdk.runApp`, unhandled exceptions are collected automatically. You can also manually report caught exceptions: +Unhandled exceptions are collected automatically when you use `DatadogSdk.runApp`. You can also report caught exceptions manually: ```dart try { @@ -166,30 +260,30 @@ try { ``` -Crash and error stacks require uploaded symbol files to resolve back to source locations. Flutter symbols, iOS dSYM, and Android mapping files are uploaded through the FlashCat CLI, and the `version` used at upload time must match the `version` in the SDK initialization. See Advanced configuration. +Crash and error stack traces need symbol files to be resolved back to source locations. Upload Flutter symbols, iOS dSYMs, and Android mapping files with the FlashCat CLI, and make sure the `version` used at upload matches the `version` passed during SDK initialization. See Advanced configuration. ## Verify the integration -After integration, verify it with these steps: +After integrating, verify it as follows: -1. Temporarily set `DatadogSdk.instance.sdkVerbosity = CoreLoggerLevel.debug` during initialization, and inspect the console logs to observe the SDK's reporting behavior -2. Run the application and trigger page navigation, taps, network requests, or a manual error -3. In the Flashduty RUM application, filter for `source:flutter` and confirm that view, action, resource, or error events appear -4. For network requests, check whether the backend receives the W3C `traceparent` +1. Temporarily set `DatadogSdk.instance.sdkVerbosity = CoreLoggerLevel.debug` during initialization to inspect the SDK's reporting behavior in the console logs +2. Run the application and trigger a page change, a tap, a network request, or a manual error +3. In your Flashduty RUM application, filter by `source:flutter` and confirm that view, action, resource, or error events appear +4. For network requests, check that your backend receives the W3C `traceparent` header ## Next steps -Configure sampling, tracking consent, event filtering, tracing, and symbol file upload. +Configure sampling rates, tracking consent, event filtering, tracing, and symbol file uploads. -Review supported platforms, Flutter versions, companion packages, and current limits. +Learn about supported platforms, Flutter versions, companion packages, and current limitations. -Review event types, fields, and upload behavior collected automatically and manually by the SDK. +See the event types, fields, and reporting behavior the SDK collects automatically and manually. diff --git a/zh/rum/sdk/flutter/advanced-config.mdx b/zh/rum/sdk/flutter/advanced-config.mdx index b8a9c8b2..6ea6f48e 100644 --- a/zh/rum/sdk/flutter/advanced-config.mdx +++ b/zh/rum/sdk/flutter/advanced-config.mdx @@ -4,7 +4,7 @@ description: "配置 Flutter RUM SDK 的采样率、隐私同意、事件过滤 keywords: ["RUM", "Flutter SDK", "高级配置", "采样", "隐私同意", "符号上传"] --- -本文介绍 Flutter SDK 的进阶配置项。所有配置都通过 `DatadogConfiguration` 与 `DatadogRumConfiguration` 传入。 +本文介绍 Flutter SDK 的进阶配置项。配置分布在两个对象上:`DatadogConfiguration` 承载 SDK 级别的设置(凭据、站点、版本、上报策略),`DatadogRumConfiguration` 承载 RUM 特性的设置(采样、自动采集开关、事件映射器)。 ## 采样率 @@ -16,6 +16,34 @@ DatadogRumConfiguration( ); ``` +`sessionSamplingRate` 与 `traceSampleRate` 的取值都会被强制收敛到 `0`–`100` 区间,传入超出范围的值不会报错,而是被截断。 + +## 应用版本与服务名 + +`version`、`service` 和 `flavor` 决定 RUM 事件的归属标签,也决定崩溃堆栈能否与符号文件匹配上。 + +```dart +DatadogConfiguration( + clientToken: '', + env: 'production', + site: FlashcatSite.cn, + service: 'com.example.shopping', + version: '1.4.2', + flavor: 'release', + rumConfiguration: DatadogRumConfiguration(applicationId: ''), +); +``` + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `service` | string | 未设置时沿用原生 SDK 的默认值 | 服务名,用于在控制台区分不同应用。上传符号文件时需与此处一致 | +| `version` | string | 取自 `pubspec.yaml` 的版本号,去掉 build 与预发布后缀 | 应用版本。需要携带完整版本信息,或 pubspec 版本与实际发版版本不一致时,显式设置 | +| `flavor` | string | `null` | 应用变体(如多渠道包)。为 `null` 时不会作为标签写入 RUM,但符号上传工具默认按 `release` 处理 | + + +`version` 是 Datadog 风格的标签,不允许出现 `+`。SDK 上报前会自动把 `+` 替换为 `-`,例如 `1.4.2+18` 会变成 `1.4.2-18`。上传符号文件时请使用替换后的值,否则堆栈无法还原。 + + ## 隐私同意 `TrackingConsent` 控制是否采集与上报数据,适配 GDPR 等合规要求: @@ -36,6 +64,8 @@ await DatadogSdk.runApp(configuration, TrackingConsent.pending, () async { DatadogSdk.instance.setTrackingConsent(TrackingConsent.granted); ``` +如果用户撤回授权,可以调用 `DatadogSdk.instance.clearAllData()` 丢弃尚未上报的本地缓存数据。 + ## 事件过滤与脱敏 事件映射器在事件上报前执行,返回 `null` 丢弃事件,或修改后返回。可用于脱敏敏感字段、去除噪声、重命名视图。 @@ -54,9 +84,13 @@ DatadogRumConfiguration( ); ``` + +`viewEventMapper` 必须返回一个事件,不能丢弃视图;其余映射器可以返回 `null` 来丢弃对应事件。映射器只能修改事件中可变(非 `final`)的属性。 + + ## 分布式追踪 -对 `firstPartyHosts` 命中的域名,SDK 会注入 W3C `traceparent`,实现前端 RUM 与后端 APM 的链路关联。追踪需要配合网络采集(`enableHttpTracking()`)。 +对 `firstPartyHosts` 命中的域名,SDK 会注入追踪头,实现前端 RUM 与后端 APM 的链路关联。追踪需要配合网络采集(`enableHttpTracking()` 或 `DatadogClient`)。 ```dart DatadogConfiguration( @@ -71,6 +105,41 @@ DatadogConfiguration( )..enableHttpTracking(); ``` +### 选择追踪头类型 + +`firstPartyHosts` 是一种简写:列出的每个域名都会同时注入 Datadog 风格的 `x-datadog-*` 头和 W3C `traceparent` 头。如果后端只接受其中一种,或不同网关使用不同协议,请改用 `firstPartyHostsWithTracingHeaders` 按域名指定: + +```dart +DatadogConfiguration( + clientToken: '', + env: 'production', + site: FlashcatSite.cn, + firstPartyHostsWithTracingHeaders: { + 'api.example.com': {TracingHeaderType.tracecontext}, + 'legacy.example.com': {TracingHeaderType.b3multi}, + }, + rumConfiguration: DatadogRumConfiguration(applicationId: ''), +); +``` + +| `TracingHeaderType` | 注入的请求头 | +|------|------| +| `datadog` | `x-datadog-trace-id`、`x-datadog-parent-id`、`x-datadog-sampling-priority` 等 | +| `tracecontext` | W3C `traceparent` / `tracestate` | +| `b3` | OpenTelemetry B3 单头模式(`b3`) | +| `b3multi` | OpenTelemetry B3 多头模式(`X-B3-TraceId` 等) | + +`firstPartyHosts` 与 `firstPartyHostsWithTracingHeaders` 可以同时传入,SDK 会取两者的并集。 + +### 控制注入时机 + +`traceContextInjection` 决定未被采样的请求是否仍然携带追踪头: + +| 取值 | 行为 | +|------|------| +| `TraceContextInjection.sampled`(默认) | 只对采样命中的请求注入追踪头 | +| `TraceContextInjection.all` | 对所有请求注入追踪头,由后端决定如何处理未采样的链路 | + ## 自定义上报地址 私有化部署时,通过 `customEndpoint` 覆盖默认上报地址: @@ -82,6 +151,18 @@ DatadogRumConfiguration( ); ``` +## 后台 isolate 采集 + +如果你在后台 isolate 中执行网络请求或业务逻辑,需要在该 isolate 内附着到已初始化的 SDK,事件才会归入同一个会话: + +```dart +await DatadogSdk.instance.attachToBackgroundIsolate(); +``` + + +必须先在主 isolate 完成初始化,`attachToBackgroundIsolate()` 才能拿到配置。在初始化完成前调用,或在不支持 isolate 的平台上调用,会打印告警并静默跳过。 + + ## 符号文件上传 要把崩溃与错误堆栈还原到源码位置,需要上传符号文件。Flutter 应用可能同时包含 Dart 与原生帧: @@ -103,12 +184,31 @@ flashcat-cli flutter-symbols upload --service --version 上传时的 `version` 与 `service` 必须与 SDK 初始化中的值完全一致,否则控制台可以收到崩溃事件,但无法把栈帧还原到源码位置。请把符号上传纳入发布构建流程。 -## 其他配置 - -| 配置 | 默认值 | 说明 | -|------|--------|------| -| `nativeCrashReportEnabled` | false | 是否采集原生崩溃 | -| `detectLongTasks` | true | 是否采集 long task | -| `longTaskThreshold` | 0.1s | long task 判定阈值 | -| `trackBackgroundEvents` | false | 是否采集应用后台期间的事件 | -| `batchSize` / `uploadFrequency` | — | 上报批量大小与频率,权衡实时性与耗电 | +## RUM 采集配置 + +以下选项都在 `DatadogRumConfiguration` 上设置。 + +| 配置 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `detectLongTasks` | bool | `true` | 是否采集 long task | +| `longTaskThreshold` | double | `0.1`(秒) | long task 判定阈值,最小值 0.02。传入更小的值会被抬到 0.02 | +| `trackFrustrations` | bool | `true` | 是否从用户操作生成 frustration 信号 | +| `trackBackgroundEvents` | bool | `false` | 是否采集无活跃视图时(含应用在后台)的事件。开启后这些事件会挂到自动创建的 background 视图上,可能产生额外会话并影响计费 | +| `trackAnonymousUser` | bool | `true` | 是否生成跨启动持久化的匿名用户 ID,用于在不采集个人信息的前提下关联同一设备的会话 | +| `vitalUpdateFrequency` | `VitalsFrequency?` | `average` | 移动端 vitals 采集频率:`frequent`(100ms)、`average`(500ms)、`rare`(1000ms)。设为 `null` 关闭 vitals 采集 | +| `reportFlutterPerformance` | bool | `false` | 是否上报 Flutter 特有的 build / raster 耗时,通过 `SchedulerBinding.addTimingsCallback` 采集 | +| `initialResourceThreshold` | double | `0.1`(秒) | 视图开始后多长时间内启动的 resource 计入 Time to Network-Settled(TNS) | +| `trackNonFatalAnrs` | `bool?` | 随平台版本 | 是否上报 Android 非致命 ANR。Android 30+ 默认关闭(噪声过大),Android 29 及以下默认开启(该版本无法上报致命 ANR) | +| `appHangThreshold` | `double?` | `null`(关闭) | iOS 应用卡顿判定阈值,单位秒。例如设为 `0.25` 表示上报持续 250ms 以上的卡顿 | +| `telemetrySampleRate` | double | `20.0` | SDK 自身遥测的采样率 | + +## 上报策略 + +以下选项都在 `DatadogConfiguration` 上设置,用于权衡数据实时性与设备资源消耗。三者默认都为 `null`,即沿用原生 SDK 的默认策略。 + +| 配置 | 类型 | 取值 | 说明 | +|------|------|------|------| +| `batchSize` | `BatchSize?` | `small` / `medium` / `large` | 单批数据的大小偏好。批次越小,单次上报越及时,但请求次数越多 | +| `uploadFrequency` | `UploadFrequency?` | `frequent` / `average` / `rare` | 尝试上报的频率 | +| `batchProcessingLevel` | `BatchProcessingLevel?` | `low` / `medium` / `high` | 单个读取/上报周期内连续处理的批次数量。`high` 单周期发送更多数据但占用更多 CPU 与内存,`low` 反之。原生默认为 `medium` | +| `nativeCrashReportEnabled` | bool | `false` | 是否采集原生 iOS / Android 崩溃 | diff --git a/zh/rum/sdk/flutter/compatible.mdx b/zh/rum/sdk/flutter/compatible.mdx index 37830079..9bc3d7f5 100644 --- a/zh/rum/sdk/flutter/compatible.mdx +++ b/zh/rum/sdk/flutter/compatible.mdx @@ -10,25 +10,32 @@ keywords: ["RUM", "Flutter SDK", "兼容性", "Dart", "iOS", "Android"] | 项目 | 支持情况 | |------|----------| -| SDK 版本 | `flashcat_flutter_plugin` 0.1.0 | +| SDK 版本 | `flashcat_flutter_plugin` 0.1.1 | | 目标平台 | **iOS 和 Android**(不支持 Flutter Web / Desktop) | -| Flutter / Dart | Flutter ≥ 3.0,Dart ≥ 3.0 | -| iOS | 部署目标 ≥ 12.0 | -| Android | `minSdkVersion` ≥ 21 | +| Flutter / Dart | Flutter ≥ 3.27.0,Dart SDK ≥ 3.6.0 | +| iOS | 部署目标 ≥ 13.0,Podfile 需启用 `use_frameworks!` | +| Android | `minSdkVersion` ≥ 23;使用 Kotlin 时版本 ≥ 2.1.0 | +| 依赖的原生 SDK | iOS 0.5.0(`Flashcat*` pods)、Android 0.4.1(`cloud.flashcat:*`) | | RUM 数据源 | 事件固定写入 `source: "flutter"` | | 实现方式 | 基于原生 iOS / Android SDK 封装的 Flutter plugin | | 数据上报 | `POST /api/v2/rum` | ## 包和能力 -| 包 | pub 名 | 说明 | -|------|------|------| -| RUM / Core / Crash | `flashcat_flutter_plugin` | 初始化、配置、RUM(view / action / resource / error / session)、原生崩溃采集 | -| HTTP 追踪 | `datadog_tracking_http_client` | 自动把 `dart:io` / `http` 请求记录为 resource 并注入追踪头(需 `dependency_overrides`,非 v1 核心) | -| WebView 追踪 | `flashcat_webview_tracking` | 关联 WebView 内的 RUM 数据 | +三个包均已发布到 pub.dev,由认证发布者 `flashcat.cloud` 维护。 + +| 能力 | pub 包名 | 版本 | 说明 | +|------|------|------|------| +| RUM / Core / 崩溃 | `flashcat_flutter_plugin` | 0.1.1 | 初始化、配置、RUM(view / action / resource / error / session)、原生崩溃采集 | +| HTTP 追踪 | `flashcat_tracking_http_client` | 0.1.0 | 通过 `enableHttpTracking()` 把 `dart:io` / `http` 请求记录为 resource 并注入追踪头;也提供 `DatadogClient` 用于精确控制 | +| WebView 追踪 | `flashcat_webview_tracking` | 0.1.0 | 通过 `trackDatadogEvents` 关联 WebView 内的 RUM 数据 | + + +两个伴生包都依赖 `flashcat_flutter_plugin: ^0.1.0`,与主包一起正常解析,无需 `dependency_overrides`。 + -Dart 类名仍沿用上游 `Datadog*` 命名,仅站点枚举 `FlashcatSite`(`.cn` 默认 / `.staging`)与包名做了品牌化。文档示例中的 `DatadogSdk`、`DatadogConfiguration`、`DatadogRumConfiguration`、`DatadogNavigationObserver` 等均为实际导出的类名。 +Dart 类名仍沿用上游 `Datadog*` 命名,仅包名与站点枚举 `FlashcatSite` 做了品牌化。文档示例中的 `DatadogSdk`、`DatadogConfiguration`、`DatadogRumConfiguration`、`DatadogNavigationObserver`、`DatadogClient` 等均为实际导出的类名。`FlashcatSite` 有 `.cn`(生产)和 `.staging`(内部使用)两个取值;`site` 是 `DatadogConfiguration` 的必填参数,需要显式传入。 ## 支持的自动采集 @@ -37,22 +44,25 @@ Dart 类名仍沿用上游 `Datadog*` 命名,仅站点枚举 `FlashcatSite`( |------|----------|------| | 自动 view | 支持 | 需为 `MaterialApp` 添加 `DatadogNavigationObserver` | | 自动 action | 支持 | 需用 `RumUserActionDetector` 包裹子树;`trackFrustrations` 默认开启 | -| 自动 resource | 支持(需伴生包) | 通过 `datadog_tracking_http_client` 的 `enableHttpTracking()` | +| 自动 resource | 支持(需伴生包) | 通过 `flashcat_tracking_http_client` 的 `enableHttpTracking()` | +| WebView 事件 | 支持(需伴生包) | 通过 `flashcat_webview_tracking` 的 `trackDatadogEvents` | | 未处理异常 | 支持 | 使用 `DatadogSdk.runApp` 时自动接管 `FlutterError.onError` / `PlatformDispatcher.onError` | | 原生崩溃 | 支持 | 需 `nativeCrashReportEnabled: true` | -| 分布式追踪 | 支持 | 对 `firstPartyHosts` 命中的域名注入 W3C `traceparent` | +| 移动端 vitals | 支持 | `vitalUpdateFrequency` 默认 `VitalsFrequency.average`(500ms) | +| Android ANR | 支持 | 通过 `trackNonFatalAnrs` 开启非致命 ANR 采集 | +| iOS 应用卡顿 | 支持 | 通过 `appHangThreshold` 设置卡顿判定阈值 | +| 分布式追踪 | 支持 | 对 `firstPartyHosts` 命中的域名注入 Datadog 与 W3C `traceparent` 追踪头 | +| 后台 isolate | 支持 | 通过 `attachToBackgroundIsolate()` 在后台 isolate 中复用已初始化的 SDK | ## 当前限制 | 限制 | 说明 | |------|------| | 平台范围 | 仅 iOS / Android;Flutter Web 与 Desktop 不支持 | -| Logs | v1 不支持日志上报(`DatadogLoggingConfiguration` 为空操作) | -| Session Replay | v1 不支持(`datadog_session_replay` 为 preview,不在核心范围) | -| 伴生包命名 | `datadog_tracking_http_client` / `datadog_session_replay` 仍以 `datadog_flutter_plugin: ^3.0.0` 声明依赖,接入本 fork 时需 `dependency_overrides` | -| dio / gql / grpc | 对应拦截包 v1 暂不适配本 fork | +| Logs | 不支持日志上报。传入 `loggingConfiguration` 会在初始化时被清空并打印告警,API 可编译但不发送任何数据 | +| Session Replay | 不支持。仓库中的 `datadog_session_replay` 仍为上游 Datadog 包,未做品牌化适配 | +| dio / gql / grpc | 对应拦截包仍指向上游 `datadog_flutter_plugin`,暂未适配本 fork | | 页面性能指标 | `reportFlutterPerformance` 默认关闭;控制台性能页当前对 Flutter 隐藏,避免展示无数据的零值 | -| pub.dev 发布 | 正式发布确认中,当前推荐使用 git 依赖 | ## 符号解析兼容性 diff --git a/zh/rum/sdk/flutter/data-collection.mdx b/zh/rum/sdk/flutter/data-collection.mdx index 922cc6b4..0c3b9cb3 100644 --- a/zh/rum/sdk/flutter/data-collection.mdx +++ b/zh/rum/sdk/flutter/data-collection.mdx @@ -12,10 +12,14 @@ keywords: ["RUM", "Flutter SDK", "数据收集", "view", "action", "resource", " |------|----------|------| | view | 路由切换(`DatadogNavigationObserver`)或手动 API | 一次页面停留,记录加载耗时、内部的 action / resource / error 数量 | | action | `RumUserActionDetector` 自动识别或 `rum.addAction` | 用户交互(tap / scroll / swipe / custom),可关联 frustration 信号 | -| resource | `enableHttpTracking()` 或 `DatadogClient` | 一次网络请求,记录 URL、方法、状态码、耗时、大小 | +| resource | `flashcat_tracking_http_client` 的 `enableHttpTracking()` 或 `DatadogClient` | 一次网络请求,记录 URL、方法、状态码、耗时、大小 | | error | 自动(未处理异常 / 原生崩溃)或 `rum.addError` | 错误与崩溃,含类型、消息、堆栈 | | long task | `detectLongTasks` 默认开启 | 超过 `longTaskThreshold`(默认 0.1s)的主线程阻塞 | +WebView 内产生的事件由 `flashcat_webview_tracking` 桥接,按上述类型合入同一个 Flutter 会话,无需单独区分。 + +移动端 vitals(CPU、内存、帧率)不是独立事件,而是按 `vitalUpdateFrequency` 采样后附加到 view 事件上。 + ## 自动采集的上下文 每个事件会自动附带以下上下文(由原生层采集): @@ -24,7 +28,9 @@ keywords: ["RUM", "Flutter SDK", "数据收集", "view", "action", "resource", " - **设备信息**:设备型号、操作系统与版本、屏幕尺寸 - **会话信息**:`session.id`,按 `sessionSamplingRate` 采样 - **连接信息**:网络类型(如可用) -- **用户信息**:通过 `setUserInfo` 设置的 `usr.id` / `usr.name` / `usr.email` +- **用户信息**:通过 `setUserInfo` 设置的 `usr.id` / `usr.name` / `usr.email`,以及 `addUserExtraInfo` 追加的自定义属性 +- **账户信息**:通过 `setAccountInfo` 设置的 `account.id` / `account.name` 及其自定义属性 +- **匿名用户 ID**:`trackAnonymousUser` 默认开启时生成,跨启动持久化,用于在未登录状态下关联同一设备的会话 ## 手动埋点 @@ -45,6 +51,9 @@ rum?.addErrorInfo('payment failed', RumErrorSource.source); // 附加全局属性(写入后续所有事件) rum?.addAttribute('tenant', 'acme'); + +// 主动结束当前会话,下一次交互开始新会话 +rum?.stopSession(); ``` ## 采样与控制 diff --git a/zh/rum/sdk/flutter/sdk-integration.mdx b/zh/rum/sdk/flutter/sdk-integration.mdx index 7419fe26..db81e369 100644 --- a/zh/rum/sdk/flutter/sdk-integration.mdx +++ b/zh/rum/sdk/flutter/sdk-integration.mdx @@ -7,7 +7,7 @@ keywords: ["RUM", "Flutter SDK", "Dart", "用户监控", "移动端监控"] Flutter SDK 基于原生 iOS / Android SDK 封装,通过 `flashcat_flutter_plugin` 提供 RUM 能力。初始化后,SDK 会把应用中的视图、用户操作、网络请求、错误和崩溃事件上报到 Flashduty RUM,并使用 `source: "flutter"` 标识数据来源。 -当前 SDK 版本为 `0.1.0`,仅支持 **iOS 和 Android** 平台(不支持 Flutter Web)。Dart 类名仍沿用上游 `Datadog*` 命名(如 `DatadogSdk`、`DatadogConfiguration`),仅包名 `flashcat_flutter_plugin` 与站点枚举 `FlashcatSite` 做了品牌化。v1 暂不包含 Logs、Session Replay、dio / gql / grpc 伴生包。 +当前 SDK 版本为 `flashcat_flutter_plugin` 0.1.1,仅支持 **iOS 和 Android** 平台(不支持 Flutter Web / Desktop)。Dart 类名仍沿用上游 `Datadog*` 命名(如 `DatadogSdk`、`DatadogConfiguration`),仅包名与站点枚举 `FlashcatSite` 做了品牌化。v1 暂不包含 Logs 与 Session Replay。 ## 前提条件 @@ -16,25 +16,29 @@ Flutter SDK 基于原生 iOS / Android SDK 封装,通过 `flashcat_flutter_plu - 在 Flashduty 控制台创建或选择一个 RUM 应用,并获取 **Application ID** 和 **Client Token** - 确认应用可以访问 `https://browser.flashcat.cloud/api/v2/rum` -- Flutter SDK ≥ 3.0,Dart ≥ 3.0;iOS 部署目标 ≥ 12.0,Android `minSdkVersion` ≥ 21 +- Flutter ≥ 3.27.0,Dart SDK ≥ 3.6.0 +- iOS 部署目标 ≥ 13.0,且 Podfile 中启用 `use_frameworks!`(Flutter 默认已启用) +- Android `minSdkVersion` ≥ 23;若使用 Kotlin,版本需 ≥ 2.1.0 - 在应用启动早期(`main()` 中)完成 SDK 初始化 ## 安装 SDK -在 `pubspec.yaml` 中添加 `flashcat_flutter_plugin`,然后执行 `flutter pub get`。 - - -`flashcat_flutter_plugin` 的 pub.dev 发布仍在确认中。为保证依赖可解析,下方示例使用 git 源。待正式发布到 pub.dev 后,可切换为 `flashcat_flutter_plugin: ^0.1.0` 的托管形式。 - +三个包都已发布到 pub.dev,由认证发布者 `flashcat.cloud` 维护。在 `pubspec.yaml` 中按需添加,然后执行 `flutter pub get`。 ```yaml pubspec.yaml dependencies: - flashcat_flutter_plugin: - git: - url: https://github.com/flashcatcloud/fc-sdk-flutter - path: packages/datadog_flutter_plugin + # RUM / Core / 崩溃采集,必选 + flashcat_flutter_plugin: ^0.1.1 + # 自动网络采集与分布式追踪,可选 + flashcat_tracking_http_client: ^0.1.0 + # WebView 数据关联,可选 + flashcat_webview_tracking: ^0.1.0 ``` + +`flashcat_tracking_http_client` 与 `flashcat_webview_tracking` 都依赖 `flashcat_flutter_plugin: ^0.1.0`,可以与主包一起正常解析,无需 `dependency_overrides`。 + + ## 初始化 SDK 建议在 `main()` 中、`runApp` 之前完成初始化。使用 `DatadogSdk.runApp` 启动应用时,SDK 会自动接管 `FlutterError.onError` 与 `PlatformDispatcher.instance.onError`,无需手动接线即可采集未处理异常。 @@ -47,8 +51,9 @@ Future main() async { final configuration = DatadogConfiguration( clientToken: '', env: 'production', - service: 'com.example.shopping', site: FlashcatSite.cn, + service: 'com.example.shopping', + version: '1.4.2', // 需与符号文件上传时的 version 一致 nativeCrashReportEnabled: true, // 采集原生 iOS / Android 崩溃 firstPartyHosts: ['api.example.com'], // 对这些域名注入分布式追踪头 rumConfiguration: DatadogRumConfiguration( @@ -64,6 +69,8 @@ Future main() async { } ``` +`clientToken`、`env` 和 `site` 是必填参数。`site` 没有隐式默认值,生产环境请显式传入 `FlashcatSite.cn`。 + 请不要在客户端代码中使用服务端密钥。`clientToken` 只用于客户端 RUM 数据上报,`applicationId` 用于归属 RUM 应用数据。 @@ -119,9 +126,11 @@ DatadogSdk.instance.rum?.addAction(RumActionType.tap, 'Checkout'); ## 采集网络请求 -自动网络采集由独立的 `datadog_tracking_http_client` 包提供,通过配置对象上的扩展方法 `enableHttpTracking()` 开启。它会全局替换 `HttpClient`,把 `dart:io` / `http` 请求记录为 RUM resource,并对 `firstPartyHosts` 命中的域名注入 W3C 追踪头。 +自动网络采集由 `flashcat_tracking_http_client` 提供,通过配置对象上的扩展方法 `enableHttpTracking()` 开启。它会全局替换 `HttpClient`,把 `dart:io` / `http` 请求记录为 RUM resource,并对 `firstPartyHosts` 命中的域名注入追踪头。 ```dart +import 'package:flashcat_tracking_http_client/flashcat_tracking_http_client.dart'; + final configuration = DatadogConfiguration( clientToken: '', env: 'production', @@ -132,12 +141,58 @@ final configuration = DatadogConfiguration( ``` -`datadog_tracking_http_client` 当前仍以 `datadog_flutter_plugin` 命名声明依赖(`^3.0.0`),与本 fork 的 `flashcat_flutter_plugin` 0.1.0 不能直接解析。启用网络采集时需要在 `pubspec.yaml` 中加 `dependency_overrides` 指向本 fork。该能力不属于 v1 核心范围,可按需接入。 +`enableHttpTracking()` 会修改 `HttpOverrides.global`。如果你的应用也需要自定义 `HttpOverrides`,请在初始化 SDK **之前**完成设置——SDK 初始化时会读取 `HttpOverrides.current`,并在其基础上创建客户端。 + + +### 使用 DatadogClient 精确控制 + +如果你只想追踪部分请求,或使用了 `cronet_http`、`cupertino_http` 这类原生 HTTP 实现(全局替换对它们不生效),可以改用 `DatadogClient` 包装 `http` 包的 `Client`: + +```dart +import 'package:flashcat_tracking_http_client/flashcat_tracking_http_client.dart'; +import 'package:http/http.dart' as http; + +final datadogClient = DatadogClient( + datadogSdk: DatadogSdk.instance, + innerClient: http.Client(), // 可选,不传则使用默认 Client +); +``` + +即使使用 `DatadogClient`,仍需在配置中声明 `firstPartyHosts` 才能启用分布式追踪。除 `cronet_http` / `cupertino_http` 场景外,不建议同时启用 `enableHttpTracking()` 与 `DatadogClient`,两者会相互干扰。 + +## 采集 WebView 数据 + +混合应用中,`flashcat_webview_tracking` 可以把 WebView 内产生的 RUM 事件桥接到 Flutter 会话中,避免 WebView 成为监控盲区。该包配合 [`webview_flutter`](https://pub.dev/packages/webview_flutter) 使用。 + +```yaml pubspec.yaml +dependencies: + webview_flutter: ^4.0.4 + flashcat_flutter_plugin: ^0.1.1 + flashcat_webview_tracking: ^0.1.0 +``` + +在 `WebViewController` 上调用 `trackDatadogEvents` 扩展方法,并传入允许桥接的 host 列表: + +```dart +import 'package:flashcat_flutter_plugin/flashcat_flutter_plugin.dart'; +import 'package:flashcat_webview_tracking/flashcat_webview_tracking.dart'; + +final webViewController = WebViewController() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..trackDatadogEvents( + DatadogSdk.instance, + ['myapp.example'], // 允许桥接的 host,其他来源的事件会被忽略 + ) + ..loadRequest(Uri.parse('https://myapp.example')); +``` + + +Android 上必须设置 `JavaScriptMode.unrestricted`,否则桥接脚本无法注入,WebView 内的事件不会上报。 ## 关联用户信息 -登录后,你可以设置当前用户。SDK 会把用户字段写入后续 RUM 事件的 `usr` 对象。 +登录后,你可以设置当前用户。SDK 会把用户字段写入后续 RUM 事件的 `usr` 对象。`id` 为必填参数。 ```dart DatadogSdk.instance.setUserInfo( @@ -145,14 +200,53 @@ DatadogSdk.instance.setUserInfo( name: 'Alice', email: 'alice@example.com', ); + +// 追加自定义用户属性,与已有属性合并;把某个属性置为 null 表示删除它 +DatadogSdk.instance.addUserExtraInfo({'plan': 'pro', 'trial': null}); ``` 用户退出登录时清除用户信息: ```dart -DatadogSdk.instance.setUserInfo(); +DatadogSdk.instance.clearUserInfo(); +``` + + +清除用户信息请使用 `clearUserInfo()`。`setUserInfo` 的 `id` 是必填命名参数,`setUserInfo()` 空调用无法通过编译。 + + +`clearUserInfo()` 会同时清空当前活跃会话与活跃视图上的 `usr` 属性。如果你希望保留它们上面已有的用户信息,请先用 `rum.stopSession()` 或 `rum.stopView()` 结束会话或视图,再执行清除。 + +## 关联账户信息 + +面向企业客户的应用可以按用户所属账户(租户、组织、团队)做归因。账户信息写入后续事件的 `account` 对象,与用户信息相互独立。 + +```dart +DatadogSdk.instance.setAccountInfo( + id: 'acct-2048', + name: 'ACME Inc.', + extraInfo: {'tier': 'enterprise'}, +); + +// 追加账户自定义属性 +DatadogSdk.instance.addAccountExtraInfo({'region': 'cn-north'}); + +// 切换或退出账户时清除 +DatadogSdk.instance.clearAccountInfo(); ``` +与 `clearUserInfo()` 一样,`clearAccountInfo()` 会清空活跃会话与活跃视图上的 `account` 属性。 + +## 清除本地缓存数据 + +如果用户撤回授权,或你需要响应数据删除诉求,可以丢弃尚未上报的本地数据: + +```dart +DatadogSdk.instance.clearAllData(); +``` + +该方法只清除还没有发送到服务端的缓存数据,已上报的数据不受影响。 + ## 上报错误 使用 `DatadogSdk.runApp` 时未处理异常会被自动采集。你也可以手动上报捕获到的异常: