|
| 1 | +--- |
| 2 | +title: Enable telemetry for feature flags in a Node.js application |
| 3 | +titleSuffix: Azure App Configuration |
| 4 | +description: Learn how to use telemetry in Node.js for feature flags in Azure App Configuration. |
| 5 | +ms.service: azure-app-configuration |
| 6 | +author: zhiyuanliang-ms |
| 7 | +ms.author: zhiyuanliang |
| 8 | +ms.topic: how-to |
| 9 | +ms.date: 06/25/2025 |
| 10 | +--- |
| 11 | + |
| 12 | +# Enable telemetry for feature flags in a Node.js application |
| 13 | + |
| 14 | +In this tutorial, you use telemetry in your Node.js application to track feature flag evaluations and custom events. Telemetry allows you to make informed decisions about your feature management strategy. You utilize the feature flag with telemetry enabled created in the [overview for enabling telemetry for feature flags](./howto-telemetry.md). Before proceeding, ensure that you create a feature flag named *Greeting* in your Configuration store with telemetry enabled. This tutorial builds on top of the tutorial for [using variant feature flags in a Node.js application](./howto-variant-feature-flags-javascript.md). |
| 15 | + |
| 16 | +## Prerequisites |
| 17 | + |
| 18 | +- The variant feature flag with telemetry enabled from [Enable telemetry for feature flags](./howto-telemetry.md). |
| 19 | +- The application from [Use variant feature flags in a Node.js application](./howto-variant-feature-flags-javascript.md). |
| 20 | + |
| 21 | +## Add telemetry to your Node.js application |
| 22 | + |
| 23 | +1. Install the following packages. |
| 24 | + |
| 25 | + ```bash |
| 26 | + npm install @microsoft/feature-management-applicationinsights-node |
| 27 | + ``` |
| 28 | + |
| 29 | +1. Open `server.js` and add the following code in the beginning to connect to Application Insights to publish telemetry. |
| 30 | + |
| 31 | + ```js |
| 32 | + const appInsightsConnectionString = process.env.APPLICATIONINSIGHTS_CONNECTION_STRING; |
| 33 | + const applicationInsights = require("applicationinsights"); |
| 34 | + applicationInsights.setup(appInsightsConnectionString).start(); |
| 35 | +
|
| 36 | + const express = require("express"); |
| 37 | + const server = express(); |
| 38 | + // existing code ... |
| 39 | + ``` |
| 40 | + |
| 41 | +1. Add the following import. |
| 42 | + |
| 43 | + ```js |
| 44 | + const { createTelemetryPublisher, trackEvent } = require("@microsoft/feature-management-applicationinsights-node"); |
| 45 | + ``` |
| 46 | +
|
| 47 | +1. Create and register the telemetry publisher when initializing the `FeatureManager`. |
| 48 | +
|
| 49 | + ```js |
| 50 | + // existing code ... |
| 51 | + const featureFlagProvider = new ConfigurationMapFeatureFlagProvider(appConfig); |
| 52 | + const publishTelemetry = createTelemetryPublisher(applicationInsights.defaultClient); |
| 53 | + featureManager = new FeatureManager(featureFlagProvider, { |
| 54 | + onFeatureEvaluated: publishTelemetry |
| 55 | + }); |
| 56 | + // existing code ... |
| 57 | + ``` |
| 58 | +
|
| 59 | + The `publishTelemetry` callback will send telemetry data each time a feature flag is evaluated. |
| 60 | +
|
| 61 | +1. Track custom events for user interactions. Modify the `/api/like` endpoint to send telemetry data to Application Insights whenever a user likes content. This helps you analyze which feature variants perform better. |
| 62 | +
|
| 63 | + ```js |
| 64 | + server.post("/api/like", (req, res) => { |
| 65 | + const { UserId } = req.body; |
| 66 | + if (UserId === undefined) { |
| 67 | + return res.status(400).send({ error: "UserId is required" }); |
| 68 | + } |
| 69 | + trackEvent(applicationInsights.defaultClient, UserId, { name: "Liked" }); |
| 70 | + res.status(200).send(); |
| 71 | + }); |
| 72 | + ``` |
| 73 | +
|
| 74 | +## Run the application |
| 75 | +
|
| 76 | +1. Application insights requires a connection string to connect to your Application Insights resource. Set the `APPLICATIONINSIGHTS_CONNECTION_STRING` environment variable to the connection string for your Application Insights resource. |
| 77 | +
|
| 78 | + ```cmd |
| 79 | + setx APPLICATIONINSIGHTS_CONNECTION_STRING "applicationinsights-connection-string" |
| 80 | + ``` |
| 81 | +
|
| 82 | + If you use PowerShell, run the following command: |
| 83 | +
|
| 84 | + ```powershell |
| 85 | + $Env:APPLICATIONINSIGHTS_CONNECTION_STRING = "applicationinsights-connection-string" |
| 86 | + ``` |
| 87 | +
|
| 88 | + If you use macOS or Linux, run the following command: |
| 89 | +
|
| 90 | + ```bash |
| 91 | + export APPLICATIONINSIGHTS_CONNECTION_STRING='applicationinsights-connection-string' |
| 92 | + ``` |
| 93 | +
|
| 94 | +1. Run the application, [see step 4 of Use variant feature flags](./howto-variant-feature-flags-javascript.md#run-the-application). |
| 95 | +
|
| 96 | +1. Create 10 different users and log into the application. As you log in with each user, you get a different message variant for some of them. ~50% of the time you get no message. 25% of the time you get the message "Hello!" and 25% of the time you get "I hope this makes your day!" |
| 97 | +
|
| 98 | +1. With some of the users click the **Like** button to trigger the telemetry event. |
| 99 | +
|
| 100 | + > [!div class="mx-imgBorder"] |
| 101 | + >  |
| 102 | +
|
| 103 | +1. Open your Application Insights resource in the Azure portal and select **Logs** under **Monitoring**. In the query window, run the following query to see the telemetry events: |
| 104 | +
|
| 105 | + ```kusto |
| 106 | + // Step 1: Get distinct users and their Variant from FeatureEvaluation |
| 107 | + let evaluated_users = |
| 108 | + customEvents |
| 109 | + | where name == "FeatureEvaluation" |
| 110 | + | extend TargetingId = tostring(customDimensions.TargetingId), |
| 111 | + Variant = tostring(customDimensions.Variant) |
| 112 | + | summarize Variant = any(Variant) by TargetingId; |
| 113 | +
|
| 114 | + // Step 2: Get distinct users who emitted a "Like" |
| 115 | + let liked_users = |
| 116 | + customEvents |
| 117 | + | where name == "Liked" |
| 118 | + | extend TargetingId = tostring(customDimensions.TargetingId) |
| 119 | + | summarize by TargetingId; |
| 120 | +
|
| 121 | + // Step 3: Join them to get only the evaluated users who also liked |
| 122 | + let hearted_users = |
| 123 | + evaluated_users |
| 124 | + | join kind=inner (liked_users) on TargetingId |
| 125 | + | summarize HeartedUsers = dcount(TargetingId) by Variant; |
| 126 | +
|
| 127 | + // Step 4: Total evaluated users per variant |
| 128 | + let total_users = |
| 129 | + evaluated_users |
| 130 | + | summarize TotalUsers = dcount(TargetingId) by Variant; |
| 131 | +
|
| 132 | + // Step 5: Combine results |
| 133 | + let combined_data = |
| 134 | + total_users |
| 135 | + | join kind=leftouter (hearted_users) on Variant |
| 136 | + | extend HeartedUsers = coalesce(HeartedUsers, 0) |
| 137 | + | extend PercentageHearted = strcat(round(HeartedUsers * 100.0 / TotalUsers, 1), "%") |
| 138 | + | project Variant, TotalUsers, HeartedUsers, PercentageHearted; |
| 139 | +
|
| 140 | + // Step 6: Add total row |
| 141 | + let total_sum = |
| 142 | + combined_data |
| 143 | + | summarize |
| 144 | + TotalUsers = sum(TotalUsers), |
| 145 | + HeartedUsers = sum(HeartedUsers) |
| 146 | + | extend |
| 147 | + Variant = "All", |
| 148 | + PercentageHearted = strcat(round(HeartedUsers * 100.0 / TotalUsers, 1), "%") |
| 149 | + | project Variant, TotalUsers, HeartedUsers, PercentageHearted; |
| 150 | +
|
| 151 | + // Step 7: Output |
| 152 | + combined_data |
| 153 | + | union (total_sum) |
| 154 | + ``` |
| 155 | +
|
| 156 | + > [!div class="mx-imgBorder"] |
| 157 | + >  |
| 158 | +
|
| 159 | + You see one "FeatureEvaluation" event for each time the quote page was loaded and one "Liked" event for each time the like button was clicked. The "FeatureEvaluation" event has a custom property called `FeatureName` with the name of the feature flag that was evaluated. Both events have a custom property called `TargetingId` with the name of the user that liked the quote. |
| 160 | +
|
| 161 | + For more information about the "FeatureEvaluation" event, go to the [Feature flag telemetry reference](./feature-flag-telemetry-reference.md) |
| 162 | +
|
| 163 | +## Additional resources |
| 164 | +
|
| 165 | +- [Quote of the Day sample](https://github.com/Azure-Samples/quote-of-the-day-javascript) |
| 166 | +
|
| 167 | +## Next steps |
| 168 | +
|
| 169 | +For the full feature rundown of the JavaScript feature management library, refer to the following document. |
| 170 | +
|
| 171 | +> [!div class="nextstepaction"] |
| 172 | +> [JavaScript Feature Management](./feature-management-javascript-reference.md) |
0 commit comments