Skip to content

Commit 89351eb

Browse files
Merge pull request #310450 from mrm9084/TargetingSpanProcessor
App Config - Python - Targeting Context Accessor
2 parents 2980aff + e5ff796 commit 89351eb

1 file changed

Lines changed: 82 additions & 2 deletions

File tree

articles/azure-app-configuration/feature-management-python-reference.md

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,8 @@ This strategy for rolling out a feature is built into the library through the in
425425

426426
### Targeting a user
427427

428-
Either a user can be specified directly in the `is_enabled` call or a `TargetingContext` can be used to specify the user and optional group.
428+
A user can either be specified directly in the `is_enabled` call, or a `TargetingContext` can be used to specify the user and optional group. The `TargetingContext` can either be passed in when calling `is_enabled` or by providing a callback to `targeting_context_accessor` when creating the `FeatureManager`.
429+
429430

430431
```python
431432
# Directly specifying the user
@@ -435,6 +436,26 @@ result = is_enabled(feature_flags, "test_user")
435436
result = is_enabled(feature_flags, TargetingContext(user_id="test_user", groups=["Ring1"]))
436437
```
437438

439+
#### Targeting context accessor
440+
441+
Instead of passing a `TargetingContext` to each `is_enabled` call, you can register a callback function with the `FeatureManager` that automatically provides the targeting context. This approach is useful when the user identity and groups can be determined from a common source, such as HTTP request headers or session data, eliminating the need to manually construct and pass the context for every feature evaluation.
442+
443+
```python
444+
from quart import request
445+
from featuremanagement import FeatureManager, TargetingContext
446+
447+
# A callback for assigning a TargetingContext for Feature Flag evaluation in a Quart app
448+
def my_targeting_accessor() -> TargetingContext:
449+
session_id = ""
450+
if "Session-ID" in request.headers:
451+
session_id = request.headers["Session-ID"]
452+
return TargetingContext(user_id=session_id)
453+
454+
455+
# Load feature flags and set up targeting context accessor
456+
feature_manager = FeatureManager(config, targeting_context_accessor=my_targeting_accessor)
457+
```
458+
438459
### Targeting exclusion
439460

440461
When defining an audience, users and groups can be excluded from the audience. Exclusions are useful for when a feature is being rolled out to a group of users, but a few users or groups need to be excluded from the rollout. Exclusion is defined by adding a list of users and groups to the `Exclusion` property of the audience.
@@ -735,7 +756,11 @@ configure_azure_monitor(
735756
)
736757
```
737758

738-
### Custom telemetry publishing
759+
### Logging telemetry events
760+
761+
The feature management library provides multiple ways to log telemetry events. You can use the built-in callback for feature flag evaluation events or manually track custom events for user interactions and application events.
762+
763+
#### Feature evaluation events
739764

740765
Because the telemetry callback is a function, it can be customized to publish telemetry to any desired destination. For example, telemetry could be published to a logging service, a database, or a custom telemetry service.
741766

@@ -749,6 +774,61 @@ When a feature flag is evaluated and telemetry is enabled, the feature manager c
749774
| `Variant` | The assigned variant. |
750775
| `VariantAssignmentReason` | The reason why the variant is assigned. |
751776

777+
#### Tracking custom events
778+
779+
Beyond automatic feature flag evaluation telemetry, you can manually track custom events using the `track_event` function. This is useful for tracking user interactions, business events, or other custom telemetry that should be correlated with feature flag usage.
780+
781+
```python
782+
from featuremanagement.azuremonitor import track_event
783+
784+
# Track a custom event with a user identifier
785+
track_event("ButtonClicked", "user123")
786+
787+
# Track an event without a user identifier
788+
track_event("ApplicationStarted")
789+
```
790+
791+
The `track_event` function accepts two parameters:
792+
793+
| Parameter | Description |
794+
| ---------------- | ---------------- |
795+
| `event_name` | The name of the event to track. |
796+
| `user` | Optional user identifier to associate with the event. |
797+
798+
Custom events are sent to the same Application Insights instance configured for feature flag telemetry, allowing you to correlate feature flag evaluations with user behavior and application events.
799+
800+
### Enriching telemetry with targeting context
801+
802+
Instead of manually passing user identifiers to each `track_event` call, you can use the `TargetingSpanProcessor` to automatically enrich all telemetry with targeting context information. The processor accepts a callback function that returns a `TargetingContext`, allowing telemetry to automatically include the user ID for each request. This enrichment helps correlate telemetry data with specific users and groups, making it easier to analyze feature flag performance for targeted audiences without requiring explicit user parameters in your telemetry calls.
803+
804+
> [!NOTE]
805+
> The `TargetingSpanProcessor` is specifically for telemetry enrichment. You still need to provide a `targeting_context_accessor` to the `FeatureManager` for feature flag evaluation, as described in the [Targeting context accessor](#targeting-context-accessor) section.
806+
807+
The following example demonstrates how to configure the processor in a Quart application, using a session ID from request headers as the user identifier. Call `configure_azure_monitor` before creating your application instance to ensure proper initialization.
808+
809+
```python
810+
import os
811+
from quart import request
812+
from azure.monitor.opentelemetry import configure_azure_monitor
813+
from featuremanagement import TargetingContext
814+
from featuremanagement.azuremonitor import TargetingSpanProcessor
815+
816+
async def my_targeting_accessor() -> TargetingContext:
817+
session_id = ""
818+
if "Session-ID" in request.headers:
819+
session_id = request.headers["Session-ID"]
820+
return TargetingContext(user_id=session_id)
821+
822+
# Configure Azure Monitor with targeting context for telemetry
823+
configure_azure_monitor(
824+
connection_string=os.getenv("APPLICATIONINSIGHTS_CONNECTION_STRING"),
825+
span_processors=[TargetingSpanProcessor(targeting_context_accessor=my_targeting_accessor)],
826+
)
827+
828+
# You must also provide the targeting context accessor to FeatureManager for evaluation
829+
feature_manager = FeatureManager(config, targeting_context_accessor=my_targeting_accessor)
830+
```
831+
752832
## Next steps
753833

754834
To learn how to use feature flags in your applications, continue to the following quickstarts.

0 commit comments

Comments
 (0)