diff --git a/hugo/config/_default/menus/main.en.yaml b/hugo/config/_default/menus/main.en.yaml index f032f12fb23..d0628f23779 100644 --- a/hugo/config/_default/menus/main.en.yaml +++ b/hugo/config/_default/menus/main.en.yaml @@ -6743,6 +6743,11 @@ menu: parent: feature_flags_concepts identifier: feature_flags_concepts_flag_key_obfuscation weight: 317 + - name: Evaluation Telemetry Opt-Out + url: feature_flags/concepts/evaluation_telemetry_opt_out + parent: feature_flags_concepts + identifier: feature_flags_concepts_evaluation_telemetry_opt_out + weight: 318 - name: Permissions and Access Control url: feature_flags/concepts/permissions parent: feature_flags_concepts diff --git a/hugo/content/en/feature_flags/client/android.md b/hugo/content/en/feature_flags/client/android.md index 787bc6d5894..b83e6793b56 100644 --- a/hugo/content/en/feature_flags/client/android.md +++ b/hugo/content/en/feature_flags/client/android.md @@ -153,6 +153,59 @@ OpenFeatureAPI.setEvaluationContext(
OpenFeature attributes must use flat Value primitives such as Value.String(), Value.Integer(), Value.Double(), or Value.Boolean(). The targeting key should be consistent for the same user to help ensure consistent flag evaluation across sessions. For anonymous users, use a persistent UUID stored, for example, in SharedPreferences.
+## Per-subject evaluation telemetry opt-out + +After initializing Datadog and enabling Flags, enable the control when you first create the client. See [availability and shared behavior][4]. + +### Provider integration + +Pass your application's decision as `Value.Boolean`, not a string: + +{{< code-block lang="kotlin" >}} +import com.datadog.android.flags.FlagsClient +import com.datadog.android.flags.openfeature.asOpenFeatureProvider +import dev.openfeature.kotlin.sdk.ImmutableContext +import dev.openfeature.kotlin.sdk.OpenFeatureAPI +import dev.openfeature.kotlin.sdk.Value + +val provider = FlagsClient.Builder() + .enableEvaluationTelemetryOptOutParameter(true) + .build() + .asOpenFeatureProvider() + +val optedOut = true // Your application determines this value. +val initialContext = ImmutableContext( + targetingKey = "user-123", + attributes = mapOf("dd_evaluation_telemetry_opt_out" to Value.Boolean(optedOut)) +) +OpenFeatureAPI.setProviderAndWait(provider, initialContext = initialContext) + +val enabled = OpenFeatureAPI.getClient().getBooleanValue("new-checkout", false) +{{< /code-block >}} + +Use `OpenFeatureAPI.setEvaluationContext()` to update the subject's decision. + +### Direct client integration + +The native client has string-valued context attributes. Use its typed setter to control telemetry: + +{{< code-block lang="kotlin" >}} +import com.datadog.android.flags.FlagsClient +import com.datadog.android.flags.model.EvaluationContext +import com.datadog.android.flags.setEvaluationTelemetryOptOut + +val client = FlagsClient.Builder() + .enableEvaluationTelemetryOptOutParameter(true) + .build() + +val optedOut = true // Your application determines this value. +client.setEvaluationTelemetryOptOut(optedOut) +client.setEvaluationContext(EvaluationContext(targetingKey = "user-123")) +val enabled = client.getBooleanValue("new-checkout", false) +{{< /code-block >}} + +A string `"true"` in the native context does not activate opt-out. Update the typed setter when the subject or preference changes. Reusing an existing client name retains its original configuration. + ## Evaluate flags After setting up your provider and evaluation context, you can read flag values throughout your app. Flag evaluation is _local and instantaneous_—the SDK uses locally cached data, so no network requests occur when evaluating flags. This makes evaluations safe to perform on the main thread. @@ -602,3 +655,4 @@ class CheckoutFlagsTest { [1]: https://openfeature.dev/ [2]: /account_management/api-app-keys/#client-tokens [3]: https://github.com/open-feature/kotlin-sdk/pull/226 +[4]: /feature_flags/concepts/evaluation_telemetry_opt_out/ diff --git a/hugo/content/en/feature_flags/client/flutter.md b/hugo/content/en/feature_flags/client/flutter.md index 8d3e52fe913..39daf47919e 100644 --- a/hugo/content/en/feature_flags/client/flutter.md +++ b/hugo/content/en/feature_flags/client/flutter.md @@ -293,6 +293,66 @@ print(details.error?.code); `FlagDetails.error` is set when the SDK returns the default value because the provider is not ready, the flag is not found, or the assignment value does not match the typed evaluation method. Successful details include the evaluated value plus assignment metadata, such as `variant` and `reason`, when Datadog returned it. +## Per-subject evaluation telemetry opt-out + +Enable the control in `DatadogFlagsConfiguration` before initializing the SDK. See [availability and shared behavior][20]. + +### Flutter plugin + +Use this plugin configuration instead of the `addPlugin` call in the SDK initialization example. Do not register the plugin twice: + +{{< code-block lang="dart" >}} +configuration.addPlugin( + const DatadogFlagsPluginConfiguration( + flagsConfiguration: DatadogFlagsConfiguration( + enableEvaluationTelemetryOptOutParameter: true, + ), + ), +); +await DatadogSdk.instance.initialize(configuration, TrackingConsent.granted); + +final client = DatadogSdk.instance.flags!.sharedClient(); +final optedOut = true; // Your application determines this value. +await client.initialize(FlagsEvaluationContext( + targetingKey: 'user-123', + attributes: {'dd_evaluation_telemetry_opt_out': optedOut}, +)); + +final enabled = client.getBooleanDetails( + key: 'new-checkout', + defaultValue: false, +).value; +{{< /code-block >}} + +### Standalone package + +For the `datadog_flags` package without the Flutter plugin, pass the same option when enabling Flags: + +{{< code-block lang="dart" >}} +await DatadogFlags.instance.enable( + configuration: DatadogFlagsConfiguration( + datadogConfig: datadogConfig, + enableEvaluationTelemetryOptOutParameter: true, + ), +); + +final client = DatadogFlags.instance.sharedClient(); +final optedOut = true; // Your application determines this value. +await client.initialize(FlagsEvaluationContext( + targetingKey: 'user-123', + attributes: {'dd_evaluation_telemetry_opt_out': optedOut}, +)); + +final enabled = client.getBooleanDetails( + key: 'new-checkout', + defaultValue: false, +).value; +{{< /code-block >}} + +In both integrations, update the decision with `client.initialize()` and the complete subject context. Keep the initialization error handling described in the setup instructions. + +[20]: /feature_flags/concepts/evaluation_telemetry_opt_out/ + ## Advanced configuration `DatadogFlagsConfiguration` controls SDK behavior: diff --git a/hugo/content/en/feature_flags/client/ios.md b/hugo/content/en/feature_flags/client/ios.md index cc0c1971ab0..2eb933aa28c 100644 --- a/hugo/content/en/feature_flags/client/ios.md +++ b/hugo/content/en/feature_flags/client/ios.md @@ -442,6 +442,58 @@ final class FeatureFlagEventObserver { } {{< /code-block >}} +## Per-subject evaluation telemetry opt-out + +After initializing Datadog and enabling Flags, enable the control when you first create the client or provider. See [availability and shared behavior][3]. + +### Native client + +Pass your application's decision as a typed Boolean in the context: + +{{< code-block lang="swift" >}} +import DatadogFlags + +let client = FlagsClient.create( + configuration: .init(enableEvaluationTelemetryOptOutParameter: true) +) +let optedOut = true // Your application determines this value. +client.setEvaluationContext( + FlagsEvaluationContext( + targetingKey: "user-123", + attributes: ["dd_evaluation_telemetry_opt_out": .bool(optedOut)] + ) +) + +let enabled = client.getBooleanValue(key: "new-checkout", defaultValue: false) +{{< /code-block >}} + +### Provider integration + +Enable the option on `DatadogProvider` and supply the initial context: + +{{< code-block lang="swift" >}} +import DatadogOpenFeatureProvider +import OpenFeature + +let provider = DatadogProvider(enableEvaluationTelemetryOptOutParameter: true) +let optedOut = true // Your application determines this value. +let context = MutableContext( + targetingKey: "user-123", + structure: MutableStructure(attributes: [ + "dd_evaluation_telemetry_opt_out": .boolean(optedOut) + ]) +) +await OpenFeatureAPI.shared.setProviderAndWait( + provider: provider, + initialContext: context +) + +let enabled = OpenFeatureAPI.shared.getClient() + .getBooleanValue(key: "new-checkout", defaultValue: false) +{{< /code-block >}} + +Update the context with `setEvaluationContext` for the native client or `setEvaluationContextAndWait` for OpenFeature. Reusing an existing client name retains its original configuration. + ## Advanced configuration The `Flags.enable()` API accepts optional configuration with options listed below. @@ -563,3 +615,4 @@ final class CheckoutFlagTests: XCTestCase { {{< partial name="whats-next/whats-next.html" >}} [2]: /account_management/api-app-keys/#client-tokens +[3]: /feature_flags/concepts/evaluation_telemetry_opt_out/ diff --git a/hugo/content/en/feature_flags/client/javascript.md b/hugo/content/en/feature_flags/client/javascript.md index e6c2f26c1b6..800c05a0380 100644 --- a/hugo/content/en/feature_flags/client/javascript.md +++ b/hugo/content/en/feature_flags/client/javascript.md @@ -106,6 +106,31 @@ await OpenFeature.setProviderAndWait(provider, evaluationContext); Most applications run several asynchronous tasks at startup, such as fetching data from another service or loading configuration. This example shows only feature flag initialization. As a best practice, start all of your startup promises together and await them as a group (for example, with `Promise.all`) right before the results are needed, rather than awaiting each one sequentially. This keeps total startup time close to the slowest task instead of the sum of all of them. +## Per-subject evaluation telemetry opt-out + +Enable the control when you create the provider. Pass your application's decision as a Boolean in the evaluation context. See [availability and shared behavior][7]. + +{{< code-block lang="javascript" >}} +import { DatadogProvider } from '@datadog/openfeature-browser'; +import { OpenFeature } from '@openfeature/web-sdk'; + +const provider = new DatadogProvider({ + clientToken: '', + env: '', + enableEvaluationTelemetryOptOutParameter: true, +}); + +const optedOut = true; // Your application determines this value. +await OpenFeature.setProviderAndWait(provider, { + targetingKey: 'user-123', + dd_evaluation_telemetry_opt_out: optedOut, +}); + +const enabled = OpenFeature.getClient().getBooleanValue('new-checkout', false); +{{< /code-block >}} + +Use `OpenFeature.setContext()` to update the decision. Keep the subject's targeting key and other required attributes. For application-managed configuration, enable the same option on `DatadogCoreProvider`; Datadog evaluation and RUM tracking hooks honor it. Exposure hooks remain enabled. + ## Evaluate flags After the provider is initialized, you can evaluate flags anywhere in your application. Flag evaluation is _local and instantaneous_—the SDK uses locally cached data, so no network requests occur when evaluating flags. @@ -368,3 +393,4 @@ The Web SDK flag shape requires `variants`, `defaultVariant`, and `disabled`. Om [4]: /feature_flags/implementation_patterns/browser_rules_based_evaluation/ [5]: /feature_flags/concepts/monthly_flag_configuration_requests/ [6]: /feature_flags/implementation_patterns/browser_rules_based_evaluation/#getting-started +[7]: /feature_flags/concepts/evaluation_telemetry_opt_out/ diff --git a/hugo/content/en/feature_flags/concepts/_index.md b/hugo/content/en/feature_flags/concepts/_index.md index c1be88168f9..bba41abc0b9 100644 --- a/hugo/content/en/feature_flags/concepts/_index.md +++ b/hugo/content/en/feature_flags/concepts/_index.md @@ -9,6 +9,7 @@ Learn how Datadog Feature Flags work and how to configure flags, environments, t {{< nextlink href="/feature_flags/concepts/environments" >}}Environments{{< /nextlink >}} {{< nextlink href="/feature_flags/concepts/variants_and_flag_types" >}}Variants and Flag Types{{< /nextlink >}} {{< nextlink href="/feature_flags/concepts/evaluation_context" >}}Evaluation Context{{< /nextlink >}} + {{< nextlink href="/feature_flags/concepts/evaluation_telemetry_opt_out" >}}Per-Subject Evaluation Telemetry Opt-Out{{< /nextlink >}} {{< nextlink href="/feature_flags/concepts/evaluation_results" >}}Flag Evaluation Results{{< /nextlink >}} {{< nextlink href="/feature_flags/concepts/targeting_rules" >}}Targeting Rules and Filters{{< /nextlink >}} {{< nextlink href="/feature_flags/concepts/targeting_attributes" >}}Targeting Attributes{{< /nextlink >}} diff --git a/hugo/content/en/feature_flags/concepts/evaluation_telemetry_opt_out.md b/hugo/content/en/feature_flags/concepts/evaluation_telemetry_opt_out.md new file mode 100644 index 00000000000..b559794d9be --- /dev/null +++ b/hugo/content/en/feature_flags/concepts/evaluation_telemetry_opt_out.md @@ -0,0 +1,95 @@ +--- +title: Per-Subject Evaluation Telemetry Opt-Out +description: Suppress new feature flag evaluation telemetry for selected users or devices without changing flag results or experiment exposures. +--- + +## Overview + +Per-subject evaluation telemetry opt-out lets your application exclude selected users or devices from feature flag monitoring data. A **subject** is the user, account, or device identified by the evaluation context's targeting key. + +This control affects feature flag evaluation reporting, not internal Datadog SDK telemetry. + +Your application determines who opts out. For example, combine a user's preference with your own eligibility rules. Pass the resulting Boolean to the SDK. You do not need to send the underlying personal information solely for this decision. + +## Availability + +The examples describe upcoming SDK support. The options are not yet available in released SDK versions. + +| SDK | Configuration and evaluation example | +| --- | --- | +| Browser JavaScript | [Browser example][1] | +| iOS, including the Swift OpenFeature provider | [iOS examples][2] | +| Android | [Android examples][3] | +| Dart and Flutter | [Dart and Flutter examples][4] | +| Go | [Go example][5] | +| Java | [Java example][6] | +| Node.js | [Node.js example][7] | +| Python | [Python example][8] | +| Ruby | [Ruby example][9] | +| PHP OpenFeature provider | [PHP example][10] | +| .NET | [.NET example][11] | + +## Enable the control + +1. Enable per-subject opt-out when you create the provider or flags client. Support is disabled by default. +2. Set `dd_evaluation_telemetry_opt_out` to Boolean `true` in the subject's evaluation context before evaluating flags. +3. Evaluate flags with the same methods as before. + +Use the exact attribute name in every language. Do not rename or capitalize it to match a language's naming conventions. Android's direct `FlagsClient` API uses a typed setter instead of its string-valued context; see the [Android example][3]. + +| Support enabled | Attribute value | New evaluation telemetry | +| --- | --- | --- | +| No | Any value | Existing behavior | +| Yes | Boolean `true` | Suppressed | +| Yes | Boolean `false` or missing | Existing behavior | +| Yes | String `"true"`, number, null, or another non-Boolean value | Existing behavior | + +Existing telemetry settings still apply. An opt-out value of `false` does not enable a telemetry channel that you disabled elsewhere. + +### Server environment variable + +Enable support before the application starts: + +{{< code-block lang="shell" >}} +export DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED=true +{{< /code-block >}} + +Then create the provider without an explicit opt-out option. The provider reads this setting when it is created. An explicit provider option overrides the environment variable, including an explicit `false`. The default is `false`. + +This setting enables the context parameter. It does not opt out every subject. For concurrent server requests, supply each subject's decision in the per-evaluation context, not a shared global context. + +## What the control changes + +When a subject opts out, the SDK suppresses new evaluation events, evaluation counts or metrics, and automatic flag annotations on traces or RUM views. The affected channels depend on which telemetry the SDK supports and your application enables. These evaluations do not contribute to the affected flag monitoring charts. + +The control does not change: + +- Flag values, targeting, or application defaults. +- Experiment participation or experiment exposure events. +- Unrelated application, trace, or RUM data. +- Custom OpenFeature hooks or manually added annotations. +- Events already queued or sent, or annotations already recorded. + +The opt-out attribute remains available to targeting rules and normal exposure reporting. If you write a targeting rule against it, that rule can change assignments. Suppression itself does not change assignments. + +This control is not a general consent system or a deletion mechanism. Assignment requests and exposure events can still contain subject data. Configure other SDK consent controls and experimentation eligibility separately when your policy requires them. + +## Update a subject's decision + +Your application owns the decision and updates it when the subject or preference changes. Client SDKs use the current evaluation context; server SDKs use the context supplied for each evaluation. Set Boolean `false` to resume normal evaluation telemetry for that subject. + +For clients that fetch assignments, switching subjects can leave the previous subject's assignments active until the refresh succeeds. If that previous subject opted out, reporting stays suppressed while those assignments remain active. An allowed new subject does not override the previous subject's decision. Changing the decision for the same subject takes effect locally without waiting for the refresh. + +Supply the decision before the first evaluation that must honor it. Keep the subject's targeting key and other required attributes when replacing a client context. + +[1]: /feature_flags/client/javascript/#per-subject-evaluation-telemetry-opt-out +[2]: /feature_flags/client/ios/#per-subject-evaluation-telemetry-opt-out +[3]: /feature_flags/client/android/#per-subject-evaluation-telemetry-opt-out +[4]: /feature_flags/client/flutter/#per-subject-evaluation-telemetry-opt-out +[5]: /feature_flags/server/go/#per-subject-evaluation-telemetry-opt-out +[6]: /feature_flags/server/java/#per-subject-evaluation-telemetry-opt-out +[7]: /feature_flags/server/nodejs/#per-subject-evaluation-telemetry-opt-out +[8]: /feature_flags/server/python/#per-subject-evaluation-telemetry-opt-out +[9]: /feature_flags/server/ruby/#per-subject-evaluation-telemetry-opt-out +[10]: /feature_flags/server/php/#per-subject-evaluation-telemetry-opt-out +[11]: /feature_flags/server/dotnet/#per-subject-evaluation-telemetry-opt-out diff --git a/hugo/content/en/feature_flags/server/dotnet.md b/hugo/content/en/feature_flags/server/dotnet.md index 311e44c95fc..d40b99de73f 100644 --- a/hugo/content/en/feature_flags/server/dotnet.md +++ b/hugo/content/en/feature_flags/server/dotnet.md @@ -166,6 +166,33 @@ var evalCtx = EvaluationContext.Builder() The targeting key is used for consistent traffic distribution (percentage rollouts). Additional attributes enable targeting rules, such as "enable for users in the US" or "enable for premium tier users" in the example above. +## Per-subject evaluation telemetry opt-out + +Configure the provider once. Supply the subject's decision in each evaluation context, not a shared global context. See [availability and shared behavior][10]. + +{{< code-block lang="csharp" >}} +using Datadog.FeatureFlags.OpenFeature; +using OpenFeature; +using OpenFeature.Model; + +var provider = new DatadogProvider(new DatadogProviderOptions +{ + EnableEvaluationTelemetryOptOutParameter = true, +}); +await Api.Instance.SetProviderAsync(provider); +var client = Api.Instance.GetClient(); + +// In a request handler: +var optedOut = true; // Your application determines this value for the subject. +var context = EvaluationContext.Builder() + .SetTargetingKey("user-123") + .Set("dd_evaluation_telemetry_opt_out", optedOut) + .Build(); +var enabled = await client.GetBooleanValueAsync("new-checkout", false, context); +{{< /code-block >}} + +Alternatively, set `DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED=true` and use `new DatadogProvider()`. An explicit option overrides the environment variable, including `false`. + ## Evaluate flags After setting up the provider and creating a client, you can evaluate flags throughout your application. Flag evaluation is local and fast—the SDK uses locally cached configuration data, so no network requests occur during evaluation. @@ -403,6 +430,7 @@ var enabled = client.GetBooleanValueAsync("flag-key", false, context); [7]: /feature_flags/concepts/flag_graphs/ [8]: /tracing/trace_collection/automatic_instrumentation/dd_libraries/dotnet-core/ [9]: /feature_flags/concepts/configuration_sources/ +[10]: /feature_flags/concepts/evaluation_telemetry_opt_out/ ## Further reading diff --git a/hugo/content/en/feature_flags/server/go.md b/hugo/content/en/feature_flags/server/go.md index 8391afb0b2d..afdb67d3999 100644 --- a/hugo/content/en/feature_flags/server/go.md +++ b/hugo/content/en/feature_flags/server/go.md @@ -190,6 +190,54 @@ evalCtx := openfeature.NewEvaluationContext( The targeting key is used for consistent traffic distribution (percentage rollouts). Additional attributes enable targeting rules, such as "enable for users in the US" or "enable for premium tier users" in the example above. +## Per-subject evaluation telemetry opt-out + +Enable the control when creating the provider, after starting the Datadog tracer. Pass each subject's decision with the evaluation. See [availability and shared behavior][6]. + +{{< code-block lang="go" >}} +package main + +import ( + "context" + "log" + + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" + ddopenfeature "github.com/DataDog/dd-trace-go/v2/openfeature" + "github.com/open-feature/go-sdk/openfeature" +) + +func main() { + tracer.Start() + defer tracer.Stop() + + enableOptOut := true + provider, err := ddopenfeature.NewDatadogProvider(ddopenfeature.ProviderConfig{ + EnableEvaluationTelemetryOptOutParameter: &enableOptOut, + }) + if err != nil { + log.Fatal(err) + } + if err := openfeature.SetProviderAndWait(provider); err != nil { + log.Fatal(err) + } + client := openfeature.NewClient("my-service") + + optedOut := true // Your application determines this value for the subject. + enabled, err := client.BooleanValue( + context.Background(), "new-checkout", false, + openfeature.NewEvaluationContext("user-123", map[string]any{ + "dd_evaluation_telemetry_opt_out": optedOut, + }), + ) + if err != nil { + log.Print(err) + } + log.Printf("New checkout enabled: %t", enabled) +} +{{< /code-block >}} + +Alternatively, set `DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED=true` and omit the provider option. A non-nil option overrides the environment variable, including a pointer to `false`. + ## Evaluate flags After setting up the provider and creating a client, you can evaluate flags throughout your application. Flag evaluation is local and fast—the SDK uses locally cached configuration data, so no network requests occur during evaluation. @@ -363,6 +411,7 @@ func TestNewCheckoutFlow(t *testing.T) { [3]: /account_management/api-app-keys/#api-keys [4]: /feature_flags/guide/server_flag_evaluation_metrics/ [5]: /feature_flags/concepts/flag_graphs/ +[6]: /feature_flags/concepts/evaluation_telemetry_opt_out/ ## Further reading diff --git a/hugo/content/en/feature_flags/server/java.md b/hugo/content/en/feature_flags/server/java.md index 8a9c0417dcb..647990694f1 100644 --- a/hugo/content/en/feature_flags/server/java.md +++ b/hugo/content/en/feature_flags/server/java.md @@ -227,6 +227,32 @@ EvaluationContext context = new MutableContext("user-123") The `targetingKey` (for example, `user-123`) is the primary identifier used for consistent flag evaluations and percentage-based rollouts. It's typically a user ID, session ID, or device ID. +## Per-subject evaluation telemetry opt-out + +Configure the provider once. Supply the subject's decision in each evaluation context, not a shared global context. See [availability and shared behavior][18]. + +{{< code-block lang="java" >}} +import datadog.trace.api.openfeature.Provider; +import dev.openfeature.sdk.Client; +import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.OpenFeatureAPI; +import dev.openfeature.sdk.Value; +import java.util.Collections; + +OpenFeatureAPI api = OpenFeatureAPI.getInstance(); +api.setProviderAndWait(new Provider( + new Provider.Options().enableEvaluationTelemetryOptOutParameter(true))); +Client client = api.getClient(); + +// In a request handler: +boolean optedOut = true; // Your application determines this value for the subject. +boolean enabled = client.getBooleanValue("new-checkout", false, + new ImmutableContext("user-123", Collections.singletonMap( + "dd_evaluation_telemetry_opt_out", new Value(optedOut)))); +{{< /code-block >}} + +Alternatively, set `DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED=true` and use `new Provider()`. An explicit provider option overrides the environment variable, including `false`. + ## Evaluate flags Evaluate feature flags using the OpenFeature client. All flag types are supported: Boolean, string, integer, double, and object. @@ -664,3 +690,4 @@ When the selected configuration path supports exposures, exposures appear only f [15]: /serverless/google_cloud_run/functions/java/?tab=maven [16]: /serverless/google_cloud_run/containers/in_container/java/ [17]: /feature_flags/implementation_patterns/serverless/#send-feature-flag-telemetry +[18]: /feature_flags/concepts/evaluation_telemetry_opt_out/ diff --git a/hugo/content/en/feature_flags/server/nodejs.md b/hugo/content/en/feature_flags/server/nodejs.md index 199eee6c1d2..0e2b797161e 100644 --- a/hugo/content/en/feature_flags/server/nodejs.md +++ b/hugo/content/en/feature_flags/server/nodejs.md @@ -176,6 +176,35 @@ Define who or what the flag evaluation applies to using an `EvaluationContext`.
Datadog Feature Flags requires evaluation context attributes to be flat primitive values: strings, numbers, and Booleans. Do not pass nested objects or arrays; they are not supported and can cause exposure data to be dropped.
+## Per-subject evaluation telemetry opt-out + +Enable the control in the existing tracer initialization, before accessing `tracer.openfeature`. See [availability and shared behavior][12]. + +{{< code-block lang="javascript" >}} +const tracer = require('dd-trace').init({ + featureFlags: { + enableEvaluationTelemetryOptOutParameter: true, + }, +}); +const { OpenFeature } = require('@openfeature/server-sdk'); + +async function main() { + await OpenFeature.setProviderAndWait(tracer.openfeature); + const client = OpenFeature.getClient(); + + const optedOut = true; // Your application determines this value for the subject. + const enabled = await client.getBooleanValue('new-checkout', false, { + targetingKey: 'user-123', + dd_evaluation_telemetry_opt_out: optedOut, + }); + console.log(enabled); +} + +main().catch(console.error); +{{< /code-block >}} + +Alternatively, set `DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED=true` and omit this option from `tracer.init()`. An explicit option overrides the environment variable, including `false`. + ## Evaluate flags After creating the `OpenFeature` client as described in the [Installing and initializing](#installing-and-initializing) section, you can start reading flag values throughout your app. Flag evaluation uses locally cached data, so no network requests occur when evaluating flags. @@ -384,3 +413,4 @@ The snippet above uses Vitest for its first-class ESM support. The same pattern [9]: /feature_flags/concepts/configuration_sources/#configure-agentless-delivery [10]: /feature_flags/concepts/configuration_sources/#use-agent-remote-configuration [11]: /feature_flags/implementation_patterns/serverless/#send-feature-flag-telemetry +[12]: /feature_flags/concepts/evaluation_telemetry_opt_out/ diff --git a/hugo/content/en/feature_flags/server/php.md b/hugo/content/en/feature_flags/server/php.md index 9a202db7c4d..f1d7124ec64 100644 --- a/hugo/content/en/feature_flags/server/php.md +++ b/hugo/content/en/feature_flags/server/php.md @@ -149,6 +149,31 @@ $context = new EvaluationContext(
Evaluation context attributes must be flat primitive values: strings, numbers, and Booleans. Nested arrays, objects, and null values are ignored for targeting and exposure reporting.
+## Per-subject evaluation telemetry opt-out + +This control applies to the PHP 8 OpenFeature provider, not the direct `DDTrace\FeatureFlags\Client` API. See [availability and shared behavior][7]. + +{{< code-block lang="php" >}} +setProvider(new DataDogProvider(enableEvaluationTelemetryOptOutParameter: true)); +$client = $api->getClient(); + +$optedOut = true; // Your application determines this value for the subject. +$context = new EvaluationContext('user-123', new Attributes([ + 'dd_evaluation_telemetry_opt_out' => $optedOut, +])); +$enabled = $client->getBooleanValue('new-checkout', false, $context); +{{< /code-block >}} + +Alternatively, set `DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED=true` before PHP starts and use `new DataDogProvider()`. An explicit option overrides the environment variable, including `false`. + ## Evaluate flags After setting up the client, you can evaluate flags throughout your application. Each flag is identified by a unique string key and evaluated with a typed method that returns a value of the expected type. If the flag does not exist or cannot be evaluated, the SDK returns the provided default value. @@ -442,3 +467,4 @@ Exposures appear in Datadog only for flags associated with an experiment. Standa [4]: /tracing/trace_collection/dd_libraries/php/ [5]: /feature_flags/concepts/environments/ [6]: /feature_flags/guide/server_flag_evaluation_metrics/ +[7]: /feature_flags/concepts/evaluation_telemetry_opt_out/ diff --git a/hugo/content/en/feature_flags/server/python.md b/hugo/content/en/feature_flags/server/python.md index dd1a09abb71..246c444bd46 100644 --- a/hugo/content/en/feature_flags/server/python.md +++ b/hugo/content/en/feature_flags/server/python.md @@ -126,6 +126,30 @@ eval_ctx = EvaluationContext( The targeting key is used for consistent traffic distribution (percentage rollouts). Additional attributes enable targeting rules, such as "enable for users in the US" or "enable for premium tier users" in the example above. +## Per-subject evaluation telemetry opt-out + +Configure the provider once. Supply the subject's decision in each evaluation context, not a shared global context. See [availability and shared behavior][12]. + +{{< code-block lang="python" >}} +from ddtrace.openfeature import DataDogProvider +from openfeature import api +from openfeature.evaluation_context import EvaluationContext + +api.set_provider(DataDogProvider( + enable_evaluation_telemetry_opt_out_parameter=True, +)) +client = api.get_client() + +# In a request handler: +opted_out = True # Your application determines this value for the subject. +enabled = client.get_boolean_value("new-checkout", False, EvaluationContext( + targeting_key="user-123", + attributes={"dd_evaluation_telemetry_opt_out": opted_out}, +)) +{{< /code-block >}} + +Alternatively, set `DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED=true` and use `DataDogProvider()`. An explicit option overrides the environment variable, including `False`. + ## Evaluate flags After setting up the provider and creating a client, you can evaluate flags throughout your application. Flag evaluation is local and fast—the SDK uses locally cached configuration data, so no network requests occur during evaluation. @@ -351,6 +375,7 @@ Verify the following: [9]: /feature_flags/concepts/configuration_sources/#use-agent-remote-configuration [10]: /feature_flags/concepts/configuration_sources/#configure-agentless-delivery [11]: /feature_flags/implementation_patterns/serverless/#send-feature-flag-telemetry +[12]: /feature_flags/concepts/evaluation_telemetry_opt_out/ ## Further reading diff --git a/hugo/content/en/feature_flags/server/ruby.md b/hugo/content/en/feature_flags/server/ruby.md index 3460dedc21b..df9df2b9745 100644 --- a/hugo/content/en/feature_flags/server/ruby.md +++ b/hugo/content/en/feature_flags/server/ruby.md @@ -118,6 +118,36 @@ context = OpenFeature::SDK::EvaluationContext.new( The targeting key is used for consistent traffic distribution (percentage rollouts). Additional attributes enable targeting rules, such as "enable for users in the US" or "enable for premium tier users" in the example above. +## Per-subject evaluation telemetry opt-out + +Configure the provider once. Supply the subject's decision in each evaluation context, not a shared global context. See [availability and shared behavior][6]. + +{{< code-block lang="ruby" >}} +require 'datadog' +require 'open_feature/sdk' +require 'datadog/open_feature/provider' + +provider = Datadog::OpenFeature::Provider.new( + enable_evaluation_telemetry_opt_out_parameter: true, +) +OpenFeature::SDK.set_provider_and_wait(provider) +client = OpenFeature::SDK.build_client + +# In a request handler: +opted_out = true # Your application determines this value for the subject. +context = OpenFeature::SDK::EvaluationContext.new( + targeting_key: 'user-123', + dd_evaluation_telemetry_opt_out: opted_out, +) +enabled = client.fetch_boolean_value( + flag_key: 'new-checkout', + default_value: false, + evaluation_context: context, +) +{{< /code-block >}} + +Alternatively, set `DD_FEATURE_FLAGS_EVALUATION_TELEMETRY_PER_SUBJECT_OPT_OUT_ENABLED=true` and omit the provider option. An explicit option overrides the environment variable, including `false`. + ## Evaluate flags After creating the `OpenFeature` client, you can start reading flag values throughout your app. Flag evaluation uses locally cached data, so no network requests occur when evaluating flags. @@ -326,3 +356,4 @@ Look for messages about: [3]: https://openfeature.dev/ [4]: /account_management/api-app-keys/#api-keys [5]: /feature_flags/guide/server_flag_evaluation_metrics/ +[6]: /feature_flags/concepts/evaluation_telemetry_opt_out/