From 020212ace84df2abe16bfba3d0f94481440fba98 Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang Date: Wed, 15 Jan 2025 17:58:09 +0800 Subject: [PATCH 1/3] add fm package version tracing --- rollup.config.mjs | 2 +- src/AzureAppConfigurationImpl.ts | 22 +++++++++++++++++++++- src/ConfigurationClientManager.ts | 3 +++ src/requestTracing/constants.ts | 4 ++++ src/requestTracing/utils.ts | 7 ++++++- 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/rollup.config.mjs b/rollup.config.mjs index 8ad51640..1fa9626f 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -4,7 +4,7 @@ import dts from "rollup-plugin-dts"; export default [ { - external: ["@azure/app-configuration", "@azure/keyvault-secrets", "@azure/core-rest-pipeline", "crypto", "dns/promises"], + external: ["@azure/app-configuration", "@azure/keyvault-secrets", "@azure/core-rest-pipeline", "crypto", "dns/promises", "@microsoft/feature-management"], input: "src/index.ts", output: [ { diff --git a/src/AzureAppConfigurationImpl.ts b/src/AzureAppConfigurationImpl.ts index 916ece49..3950e35d 100644 --- a/src/AzureAppConfigurationImpl.ts +++ b/src/AzureAppConfigurationImpl.ts @@ -33,6 +33,7 @@ import { CONDITIONS_KEY_NAME, CLIENT_FILTERS_KEY_NAME } from "./featureManagement/constants.js"; +import { FM_PACKAGE_NAME } from "./requestTracing/constants.js"; import { AzureKeyVaultKeyValueAdapter } from "./keyvault/AzureKeyVaultKeyValueAdapter.js"; import { RefreshTimer } from "./refresh/RefreshTimer.js"; import { RequestTracingOptions, getConfigurationSettingWithTrace, listConfigurationSettingsWithTrace, requestTracingEnabled } from "./requestTracing/utils.js"; @@ -66,6 +67,9 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { #isFailoverRequest: boolean = false; #featureFlagTracing: FeatureFlagTracingOptions | undefined; + #isPackageInspected: boolean = false; + #fmVersion: string | undefined; + // Refresh #refreshInProgress: boolean = false; @@ -184,7 +188,8 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { initialLoadCompleted: this.#isInitialLoadCompleted, replicaCount: this.#clientManager.getReplicaCount(), isFailoverRequest: this.#isFailoverRequest, - featureFlagTracing: this.#featureFlagTracing + featureFlagTracing: this.#featureFlagTracing, + fmVersion: this.#fmVersion }; } @@ -226,6 +231,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { * Loads the configuration store for the first time. */ async load() { + await this.#ensurePackageInspected(); await this.#loadSelectedAndWatchedKeyValues(); if (this.#featureFlagEnabled) { await this.#loadFeatureFlags(); @@ -281,6 +287,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { * Refreshes the configuration. */ async refresh(): Promise { + await this.#ensurePackageInspected(); if (!this.#refreshEnabled && !this.#featureFlagRefreshEnabled) { throw new Error("Refresh is not enabled for key-values or feature flags."); } @@ -316,6 +323,19 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { return new Disposable(remove); } + async #ensurePackageInspected() { + if (!this.#isPackageInspected) { + this.#isPackageInspected = true; + try { + // get feature management package version + const fmPackage = await import(FM_PACKAGE_NAME); + this.#fmVersion = fmPackage?.VERSION; + } catch (error) { + // ignore the error + } + } + } + async #refreshTasks(): Promise { const refreshTasks: Promise[] = []; if (this.#refreshEnabled) { diff --git a/src/ConfigurationClientManager.ts b/src/ConfigurationClientManager.ts index 92e16a3a..7ad8e597 100644 --- a/src/ConfigurationClientManager.ts +++ b/src/ConfigurationClientManager.ts @@ -85,6 +85,9 @@ export class ConfigurationClientManager { this.#isFailoverable = false; return; } + if (this.#dns) { + return; + } try { this.#dns = await import("dns/promises"); diff --git a/src/requestTracing/constants.ts b/src/requestTracing/constants.ts index 5a88b0fc..5e3f6174 100644 --- a/src/requestTracing/constants.ts +++ b/src/requestTracing/constants.ts @@ -55,6 +55,10 @@ export const FAILOVER_REQUEST_TAG = "Failover"; export const FEATURES_KEY = "Features"; export const LOAD_BALANCE_CONFIGURED_TAG = "LB"; +// Feature management package version +export const FM_PACKAGE_NAME = "@microsoft/feature-management"; +export const FM_VERSION_KEY = "FMJsVer"; + // Feature flag usage tracing export const FEATURE_FILTER_TYPE_KEY = "Filter"; export const CUSTOM_FILTER_KEY = "CSTM"; diff --git a/src/requestTracing/utils.ts b/src/requestTracing/utils.ts index b56c460c..2e8b1124 100644 --- a/src/requestTracing/utils.ts +++ b/src/requestTracing/utils.ts @@ -27,7 +27,8 @@ import { REPLICA_COUNT_KEY, FAILOVER_REQUEST_TAG, FEATURES_KEY, - LOAD_BALANCE_CONFIGURED_TAG + LOAD_BALANCE_CONFIGURED_TAG, + FM_VERSION_KEY } from "./constants"; export interface RequestTracingOptions { @@ -37,6 +38,7 @@ export interface RequestTracingOptions { replicaCount: number; isFailoverRequest: boolean; featureFlagTracing: FeatureFlagTracingOptions | undefined; + fmVersion: string | undefined; } // Utils @@ -119,6 +121,9 @@ export function createCorrelationContextHeader(requestTracingOptions: RequestTra if (requestTracingOptions.replicaCount > 0) { keyValues.set(REPLICA_COUNT_KEY, requestTracingOptions.replicaCount.toString()); } + if (requestTracingOptions.fmVersion) { + keyValues.set(FM_VERSION_KEY, requestTracingOptions.fmVersion); + } // Compact tags: Features=LB+... if (appConfigOptions?.loadBalancingEnabled) { From 2e2c6ff7f30494f3285cd6ed1e63b2330a1cb70b Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang Date: Wed, 15 Jan 2025 18:02:23 +0800 Subject: [PATCH 2/3] update comment --- src/requestTracing/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/requestTracing/constants.ts b/src/requestTracing/constants.ts index 5e3f6174..74ca58bb 100644 --- a/src/requestTracing/constants.ts +++ b/src/requestTracing/constants.ts @@ -55,7 +55,7 @@ export const FAILOVER_REQUEST_TAG = "Failover"; export const FEATURES_KEY = "Features"; export const LOAD_BALANCE_CONFIGURED_TAG = "LB"; -// Feature management package version +// Feature management package export const FM_PACKAGE_NAME = "@microsoft/feature-management"; export const FM_VERSION_KEY = "FMJsVer"; From fadc74c61ca66bea309667f89990e1dab61dbecc Mon Sep 17 00:00:00 2001 From: Zhiyuan Liang Date: Mon, 10 Feb 2025 12:32:07 +0800 Subject: [PATCH 3/3] update --- src/AzureAppConfigurationImpl.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/AzureAppConfigurationImpl.ts b/src/AzureAppConfigurationImpl.ts index 3950e35d..9a21fdd4 100644 --- a/src/AzureAppConfigurationImpl.ts +++ b/src/AzureAppConfigurationImpl.ts @@ -66,8 +66,6 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { #isInitialLoadCompleted: boolean = false; #isFailoverRequest: boolean = false; #featureFlagTracing: FeatureFlagTracingOptions | undefined; - - #isPackageInspected: boolean = false; #fmVersion: string | undefined; // Refresh @@ -231,7 +229,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { * Loads the configuration store for the first time. */ async load() { - await this.#ensurePackageInspected(); + await this.#inspectFmPackage(); await this.#loadSelectedAndWatchedKeyValues(); if (this.#featureFlagEnabled) { await this.#loadFeatureFlags(); @@ -287,7 +285,6 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { * Refreshes the configuration. */ async refresh(): Promise { - await this.#ensurePackageInspected(); if (!this.#refreshEnabled && !this.#featureFlagRefreshEnabled) { throw new Error("Refresh is not enabled for key-values or feature flags."); } @@ -323,9 +320,11 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration { return new Disposable(remove); } - async #ensurePackageInspected() { - if (!this.#isPackageInspected) { - this.#isPackageInspected = true; + /** + * Inspects the feature management package version. + */ + async #inspectFmPackage() { + if (this.#requestTracingEnabled && !this.#fmVersion) { try { // get feature management package version const fmPackage = await import(FM_PACKAGE_NAME);