@azure/monitor-opentelemetry 1.18.1 → 1.18.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +5 -1
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/metrics/handler.d.ts.map +1 -1
- package/dist/commonjs/metrics/handler.js +2 -3
- package/dist/commonjs/metrics/handler.js.map +1 -1
- package/dist/commonjs/metrics/quickpulse/export/sender.d.ts +10 -0
- package/dist/commonjs/metrics/quickpulse/export/sender.d.ts.map +1 -1
- package/dist/commonjs/metrics/quickpulse/export/sender.js +37 -8
- package/dist/commonjs/metrics/quickpulse/export/sender.js.map +1 -1
- package/dist/commonjs/metrics/quickpulse/filtering/filter.d.ts.map +1 -1
- package/dist/commonjs/metrics/quickpulse/filtering/filter.js +2 -5
- package/dist/commonjs/metrics/quickpulse/filtering/filter.js.map +1 -1
- package/dist/commonjs/metrics/quickpulse/liveMetrics.d.ts +4 -2
- package/dist/commonjs/metrics/quickpulse/liveMetrics.d.ts.map +1 -1
- package/dist/commonjs/metrics/quickpulse/liveMetrics.js +71 -16
- package/dist/commonjs/metrics/quickpulse/liveMetrics.js.map +1 -1
- package/dist/commonjs/metrics/quickpulse/redirectUtils.d.ts +28 -0
- package/dist/commonjs/metrics/quickpulse/redirectUtils.d.ts.map +1 -0
- package/dist/commonjs/metrics/quickpulse/redirectUtils.js +80 -0
- package/dist/commonjs/metrics/quickpulse/redirectUtils.js.map +1 -0
- package/dist/commonjs/metrics/quickpulse/utils.d.ts.map +1 -1
- package/dist/commonjs/metrics/quickpulse/utils.js.map +1 -1
- package/dist/commonjs/metrics/standardMetrics.js.map +1 -1
- package/dist/commonjs/traces/handler.d.ts +12 -0
- package/dist/commonjs/traces/handler.d.ts.map +1 -1
- package/dist/commonjs/traces/handler.js +30 -1
- package/dist/commonjs/traces/handler.js.map +1 -1
- package/dist/commonjs/tsdoc-metadata.json +1 -1
- package/dist/commonjs/types.d.ts +1 -1
- package/dist/commonjs/types.js +1 -1
- package/dist/commonjs/types.js.map +1 -1
- package/dist/commonjs/utils/azureSdkTracingBridge.d.ts +18 -0
- package/dist/commonjs/utils/azureSdkTracingBridge.d.ts.map +1 -0
- package/dist/commonjs/utils/azureSdkTracingBridge.js +35 -0
- package/dist/commonjs/utils/azureSdkTracingBridge.js.map +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +5 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/metrics/handler.d.ts.map +1 -1
- package/dist/esm/metrics/handler.js +2 -3
- package/dist/esm/metrics/handler.js.map +1 -1
- package/dist/esm/metrics/quickpulse/export/sender.d.ts +10 -0
- package/dist/esm/metrics/quickpulse/export/sender.d.ts.map +1 -1
- package/dist/esm/metrics/quickpulse/export/sender.js +37 -8
- package/dist/esm/metrics/quickpulse/export/sender.js.map +1 -1
- package/dist/esm/metrics/quickpulse/filtering/filter.d.ts.map +1 -1
- package/dist/esm/metrics/quickpulse/filtering/filter.js +2 -5
- package/dist/esm/metrics/quickpulse/filtering/filter.js.map +1 -1
- package/dist/esm/metrics/quickpulse/liveMetrics.d.ts +4 -2
- package/dist/esm/metrics/quickpulse/liveMetrics.d.ts.map +1 -1
- package/dist/esm/metrics/quickpulse/liveMetrics.js +71 -16
- package/dist/esm/metrics/quickpulse/liveMetrics.js.map +1 -1
- package/dist/esm/metrics/quickpulse/redirectUtils.d.ts +28 -0
- package/dist/esm/metrics/quickpulse/redirectUtils.d.ts.map +1 -0
- package/dist/esm/metrics/quickpulse/redirectUtils.js +76 -0
- package/dist/esm/metrics/quickpulse/redirectUtils.js.map +1 -0
- package/dist/esm/metrics/quickpulse/utils.d.ts.map +1 -1
- package/dist/esm/metrics/quickpulse/utils.js.map +1 -1
- package/dist/esm/metrics/standardMetrics.js.map +1 -1
- package/dist/esm/traces/handler.d.ts +12 -0
- package/dist/esm/traces/handler.d.ts.map +1 -1
- package/dist/esm/traces/handler.js +29 -1
- package/dist/esm/traces/handler.js.map +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/types.js +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/utils/azureSdkTracingBridge.d.ts +18 -0
- package/dist/esm/utils/azureSdkTracingBridge.d.ts.map +1 -0
- package/dist/esm/utils/azureSdkTracingBridge.js +34 -0
- package/dist/esm/utils/azureSdkTracingBridge.js.map +1 -0
- package/package.json +29 -20
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { metrics, trace } from \"@opentelemetry/api\";\nimport { logs } from \"@opentelemetry/api-logs\";\nimport type { NodeSDKConfiguration } from \"@opentelemetry/sdk-node\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport type { MetricReader, ViewOptions } from \"@opentelemetry/sdk-metrics\";\nimport { InternalConfig } from \"./shared/config.js\";\nimport { MetricHandler } from \"./metrics/index.js\";\nimport { TraceHandler } from \"./traces/handler.js\";\nimport { LogHandler } from \"./logs/index.js\";\nimport type {\n StatsbeatFeatures,\n StatsbeatInstrumentations,\n AzureMonitorOpenTelemetryOptions,\n InstrumentationOptions,\n BrowserSdkLoaderOptions,\n} from \"./types.js\";\nimport {\n AZURE_MONITOR_OPENTELEMETRY_VERSION,\n APPLICATIONINSIGHTS_SDKSTATS_DISABLED,\n} from \"./types.js\";\nimport { BrowserSdkLoader } from \"./browserSdkLoader/browserSdkLoader.js\";\nimport { setSdkPrefix } from \"./metrics/quickpulse/utils.js\";\nimport type { SpanProcessor } from \"@opentelemetry/sdk-trace-base\";\nimport type { LogRecordProcessor } from \"@opentelemetry/sdk-logs\";\nimport { getInstance } from \"./utils/statsbeat.js\";\nimport { patchOpenTelemetryInstrumentationEnable } from \"./utils/opentelemetryInstrumentationPatcher.js\";\nimport { isFunctionApp, parseResourceDetectorsFromEnvVar } from \"./utils/common.js\";\nimport { Logger } from \"./shared/logging/index.js\";\nimport { AZURE_MONITOR_AUTO_ATTACH } from \"./types.js\";\nimport { SEMRESATTRS_K8S_CLUSTER_NAME } from \"@opentelemetry/semantic-conventions\";\n\n/**\n * Semantic attribute for cloud resource ID, defined by \\@opentelemetry/resource-detector-azure\n * @internal\n */\nconst CLOUD_RESOURCE_ID_ATTRIBUTE = \"cloud.resource_id\";\n\nexport type { AzureMonitorOpenTelemetryOptions, InstrumentationOptions, BrowserSdkLoaderOptions };\n\nprocess.env[\"AZURE_MONITOR_DISTRO_VERSION\"] = AZURE_MONITOR_OPENTELEMETRY_VERSION;\n\nlet sdk: NodeSDK;\nlet browserSdkLoader: BrowserSdkLoader | undefined;\n\n/**\n * Check if auto-attach (autoinstrumentation) is enabled and warn about double instrumentation.\n */\nfunction sendAttachWarning(): void {\n if (process.env[AZURE_MONITOR_AUTO_ATTACH] === \"true\" && !isFunctionApp()) {\n // TODO: When AKS attach is public, update this message with disablement instructions for AKS\n const message =\n \"Distro detected that automatic instrumentation may have occurred. Only use autoinstrumentation if you \" +\n \"are not using manual instrumentation of OpenTelemetry in your code, such as with \" +\n \"@azure/monitor-opentelemetry or @azure/monitor-opentelemetry-exporter. For App Service resources, disable \" +\n \"autoinstrumentation in the Application Insights experience on your App Service resource or by setting \" +\n \"the ApplicationInsightsAgent_EXTENSION_VERSION app setting to 'disabled'.\";\n // Surface in the log stream\n console.warn(message);\n // Also log via diagnostic logging\n Logger.getInstance().warn(message);\n }\n}\n\n/**\n * Initialize Azure Monitor Distro\n * @param options - Azure Monitor OpenTelemetry Options\n */\nexport function useAzureMonitor(options?: AzureMonitorOpenTelemetryOptions): void {\n const config = new InternalConfig(options);\n patchOpenTelemetryInstrumentationEnable();\n const statsbeatInstrumentations: StatsbeatInstrumentations = {\n // Instrumentations\n azureSdk: config.instrumentationOptions?.azureSdk?.enabled,\n mongoDb: config.instrumentationOptions?.mongoDb?.enabled,\n mySql: config.instrumentationOptions?.mySql?.enabled,\n postgreSql: config.instrumentationOptions?.postgreSql?.enabled,\n redis: config.instrumentationOptions?.redis?.enabled,\n bunyan: config.instrumentationOptions?.bunyan?.enabled,\n winston: config.instrumentationOptions?.winston?.enabled,\n };\n // Check if the AKS resource detector successfully populated specific resource attributes\n // (k8s.cluster.name or cloud.resource_id) beyond the basic cloud.platform/cloud.provider\n // Derive from config.resource.attributes which already includes the AKS detector results\n const resourceAttributes = config.resource.attributes;\n const aksResourceDetected =\n SEMRESATTRS_K8S_CLUSTER_NAME in resourceAttributes ||\n CLOUD_RESOURCE_ID_ATTRIBUTE in resourceAttributes;\n const statsbeatFeatures: StatsbeatFeatures = {\n browserSdkLoader: config.browserSdkLoaderOptions.enabled,\n aadHandling: !!config.azureMonitorExporterOptions?.credential,\n diskRetry: !config.azureMonitorExporterOptions?.disableOfflineStorage,\n customerSdkStats: process.env[APPLICATIONINSIGHTS_SDKSTATS_DISABLED]?.toLowerCase() === \"true\",\n aksResourceDetectorPopulation: aksResourceDetected,\n };\n getInstance().setStatsbeatFeatures(statsbeatInstrumentations, statsbeatFeatures);\n\n if (config.browserSdkLoaderOptions.enabled) {\n browserSdkLoader = new BrowserSdkLoader(config);\n }\n // Remove global providers in OpenTelemetry, these would be overridden if present\n metrics.disable();\n trace.disable();\n logs.disable();\n\n // Clear the entire OpenTelemetry API global state to avoid version conflicts.\n // The disable() calls above remove individual providers but leave the `version` field\n // on the global object intact. If a different version of @opentelemetry/api was loaded\n // first (e.g. by a VS Code extension host or another extension), the stale version\n // causes registerGlobal() in sdk.start() to fail with \"All API registration versions\n // must match\", resulting in Noop providers. Deleting the global object forces\n // registerGlobal() to create a fresh one with the correct version.\n const globalOpentelemetryApiKey = Symbol.for(\"opentelemetry.js.api.1\");\n delete (globalThis as Record<symbol, unknown>)[globalOpentelemetryApiKey];\n\n // Create internal handlers\n const metricHandler = new MetricHandler(config);\n const traceHandler = new TraceHandler(config, metricHandler);\n const logHandler = new LogHandler(config, metricHandler);\n\n const instrumentations = traceHandler\n .getInstrumentations()\n .concat(logHandler.getInstrumentations());\n\n const resourceDetectorsList = parseResourceDetectorsFromEnvVar();\n\n // Add extra SpanProcessors, and logRecordProcessors from user configuration\n const spanProcessors: SpanProcessor[] = options?.spanProcessors || [];\n const logRecordProcessors: LogRecordProcessor[] = options?.logRecordProcessors || [];\n const customViews: ViewOptions[] = options?.views || [];\n\n // Prepare metric readers - always include Azure Monitor\n const metricReaders: MetricReader[] = [\n metricHandler.getMetricReader(),\n ...(options?.metricReaders || []),\n ];\n\n const views: ViewOptions[] = metricHandler.getViews().concat(customViews);\n\n // Initialize OpenTelemetry SDK\n const sdkConfig: Partial<NodeSDKConfiguration> = {\n autoDetectResources: true,\n metricReaders: metricReaders,\n views,\n instrumentations: instrumentations,\n logRecordProcessors: [\n logHandler.getAzureLogRecordProcessor(),\n ...logRecordProcessors,\n logHandler.getBatchLogRecordProcessor(),\n ],\n resource: config.resource,\n sampler: traceHandler.getSampler(),\n spanProcessors: [\n traceHandler.getAzureMonitorSpanProcessor(),\n ...spanProcessors,\n traceHandler.getBatchSpanProcessor(),\n ],\n resourceDetectors: resourceDetectorsList,\n };\n sdk = new NodeSDK(sdkConfig);\n setSdkPrefix();\n sendAttachWarning();\n sdk.start();\n}\n\n/**\n * Shutdown Azure Monitor Open Telemetry Distro\n * @see https://github.com/open-telemetry/opentelemetry-js/blob/0229434cb5a3179f63c021105f36270ae7897929/experimental/packages/opentelemetry-sdk-node/src/sdk.ts#L398\n */\nexport function shutdownAzureMonitor(): Promise<void> {\n browserSdkLoader?.dispose();\n return sdk?.shutdown();\n}\n\n/**\n * Get the internal SDK instance for testing purposes\n * @internal\n */\n// eslint-disable-next-line no-underscore-dangle\nexport function _getSdkInstance(): NodeSDK | undefined {\n return sdk;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { metrics, trace } from \"@opentelemetry/api\";\nimport { logs } from \"@opentelemetry/api-logs\";\nimport type { NodeSDKConfiguration } from \"@opentelemetry/sdk-node\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport type { MetricReader, ViewOptions } from \"@opentelemetry/sdk-metrics\";\nimport { InternalConfig } from \"./shared/config.js\";\nimport { MetricHandler } from \"./metrics/index.js\";\nimport { TraceHandler } from \"./traces/handler.js\";\nimport { LogHandler } from \"./logs/index.js\";\nimport type {\n StatsbeatFeatures,\n StatsbeatInstrumentations,\n AzureMonitorOpenTelemetryOptions,\n InstrumentationOptions,\n BrowserSdkLoaderOptions,\n} from \"./types.js\";\nimport {\n AZURE_MONITOR_OPENTELEMETRY_VERSION,\n APPLICATIONINSIGHTS_SDKSTATS_DISABLED,\n} from \"./types.js\";\nimport { BrowserSdkLoader } from \"./browserSdkLoader/browserSdkLoader.js\";\nimport { setSdkPrefix } from \"./metrics/quickpulse/utils.js\";\nimport type { SpanProcessor } from \"@opentelemetry/sdk-trace-base\";\nimport type { LogRecordProcessor } from \"@opentelemetry/sdk-logs\";\nimport { getInstance } from \"./utils/statsbeat.js\";\nimport { patchOpenTelemetryInstrumentationEnable } from \"./utils/opentelemetryInstrumentationPatcher.js\";\nimport { ensureAzureSdkTracingBridge } from \"./utils/azureSdkTracingBridge.js\";\nimport { isFunctionApp, parseResourceDetectorsFromEnvVar } from \"./utils/common.js\";\nimport { Logger } from \"./shared/logging/index.js\";\nimport { AZURE_MONITOR_AUTO_ATTACH } from \"./types.js\";\nimport { SEMRESATTRS_K8S_CLUSTER_NAME } from \"@opentelemetry/semantic-conventions\";\n\n/**\n * Semantic attribute for cloud resource ID, defined by \\@opentelemetry/resource-detector-azure\n * @internal\n */\nconst CLOUD_RESOURCE_ID_ATTRIBUTE = \"cloud.resource_id\";\n\nexport type { AzureMonitorOpenTelemetryOptions, InstrumentationOptions, BrowserSdkLoaderOptions };\n\nprocess.env[\"AZURE_MONITOR_DISTRO_VERSION\"] = AZURE_MONITOR_OPENTELEMETRY_VERSION;\n\nlet sdk: NodeSDK;\nlet browserSdkLoader: BrowserSdkLoader | undefined;\n\n/**\n * Check if auto-attach (autoinstrumentation) is enabled and warn about double instrumentation.\n */\nfunction sendAttachWarning(): void {\n if (process.env[AZURE_MONITOR_AUTO_ATTACH] === \"true\" && !isFunctionApp()) {\n // TODO: When AKS attach is public, update this message with disablement instructions for AKS\n const message =\n \"Distro detected that automatic instrumentation may have occurred. Only use autoinstrumentation if you \" +\n \"are not using manual instrumentation of OpenTelemetry in your code, such as with \" +\n \"@azure/monitor-opentelemetry or @azure/monitor-opentelemetry-exporter. For App Service resources, disable \" +\n \"autoinstrumentation in the Application Insights experience on your App Service resource or by setting \" +\n \"the ApplicationInsightsAgent_EXTENSION_VERSION app setting to 'disabled'.\";\n // Surface in the log stream\n console.warn(message);\n // Also log via diagnostic logging\n Logger.getInstance().warn(message);\n }\n}\n\n/**\n * Initialize Azure Monitor Distro\n * @param options - Azure Monitor OpenTelemetry Options\n */\nexport function useAzureMonitor(options?: AzureMonitorOpenTelemetryOptions): void {\n const config = new InternalConfig(options);\n patchOpenTelemetryInstrumentationEnable();\n const statsbeatInstrumentations: StatsbeatInstrumentations = {\n // Instrumentations\n azureSdk: config.instrumentationOptions?.azureSdk?.enabled,\n mongoDb: config.instrumentationOptions?.mongoDb?.enabled,\n mySql: config.instrumentationOptions?.mySql?.enabled,\n postgreSql: config.instrumentationOptions?.postgreSql?.enabled,\n redis: config.instrumentationOptions?.redis?.enabled,\n bunyan: config.instrumentationOptions?.bunyan?.enabled,\n winston: config.instrumentationOptions?.winston?.enabled,\n };\n // Check if the AKS resource detector successfully populated specific resource attributes\n // (k8s.cluster.name or cloud.resource_id) beyond the basic cloud.platform/cloud.provider\n // Derive from config.resource.attributes which already includes the AKS detector results\n const resourceAttributes = config.resource.attributes;\n const aksResourceDetected =\n SEMRESATTRS_K8S_CLUSTER_NAME in resourceAttributes ||\n CLOUD_RESOURCE_ID_ATTRIBUTE in resourceAttributes;\n const statsbeatFeatures: StatsbeatFeatures = {\n browserSdkLoader: config.browserSdkLoaderOptions.enabled,\n aadHandling: !!config.azureMonitorExporterOptions?.credential,\n diskRetry: !config.azureMonitorExporterOptions?.disableOfflineStorage,\n customerSdkStats: process.env[APPLICATIONINSIGHTS_SDKSTATS_DISABLED]?.toLowerCase() === \"true\",\n aksResourceDetectorPopulation: aksResourceDetected,\n };\n getInstance().setStatsbeatFeatures(statsbeatInstrumentations, statsbeatFeatures);\n\n if (config.browserSdkLoaderOptions.enabled) {\n browserSdkLoader = new BrowserSdkLoader(config);\n }\n // Remove global providers in OpenTelemetry, these would be overridden if present\n metrics.disable();\n trace.disable();\n logs.disable();\n\n // Clear the entire OpenTelemetry API global state to avoid version conflicts.\n // The disable() calls above remove individual providers but leave the `version` field\n // on the global object intact. If a different version of @opentelemetry/api was loaded\n // first (e.g. by a VS Code extension host or another extension), the stale version\n // causes registerGlobal() in sdk.start() to fail with \"All API registration versions\n // must match\", resulting in Noop providers. Deleting the global object forces\n // registerGlobal() to create a fresh one with the correct version.\n const globalOpentelemetryApiKey = Symbol.for(\"opentelemetry.js.api.1\");\n Reflect.deleteProperty(globalThis, globalOpentelemetryApiKey);\n\n // Create internal handlers\n const metricHandler = new MetricHandler(config);\n const traceHandler = new TraceHandler(config, metricHandler);\n const logHandler = new LogHandler(config, metricHandler);\n\n const instrumentations = traceHandler\n .getInstrumentations()\n .concat(logHandler.getInstrumentations());\n\n const resourceDetectorsList = parseResourceDetectorsFromEnvVar();\n\n // Add extra SpanProcessors, and logRecordProcessors from user configuration\n const spanProcessors: SpanProcessor[] = options?.spanProcessors || [];\n const logRecordProcessors: LogRecordProcessor[] = options?.logRecordProcessors || [];\n const customViews: ViewOptions[] = options?.views || [];\n\n // Prepare metric readers - always include Azure Monitor\n const metricReaders: MetricReader[] = [\n metricHandler.getMetricReader(),\n ...(options?.metricReaders || []),\n ];\n\n const views: ViewOptions[] = metricHandler.getViews().concat(customViews);\n\n // Initialize OpenTelemetry SDK\n const sdkConfig: Partial<NodeSDKConfiguration> = {\n autoDetectResources: true,\n metricReaders: metricReaders,\n views,\n instrumentations: instrumentations,\n logRecordProcessors: [\n logHandler.getAzureLogRecordProcessor(),\n ...logRecordProcessors,\n logHandler.getBatchLogRecordProcessor(),\n ],\n resource: config.resource,\n sampler: traceHandler.getSampler(),\n spanProcessors: [\n traceHandler.getAzureMonitorSpanProcessor(),\n ...spanProcessors,\n traceHandler.getBatchSpanProcessor(),\n ],\n resourceDetectors: resourceDetectorsList,\n };\n sdk = new NodeSDK(sdkConfig);\n setSdkPrefix();\n sendAttachWarning();\n sdk.start();\n\n // Eagerly install the Azure SDK tracing bridge in case @azure/core-tracing\n // was loaded before useAzureMonitor() (the RITM hook misses it otherwise).\n ensureAzureSdkTracingBridge();\n}\n\n/**\n * Shutdown Azure Monitor Open Telemetry Distro\n * @see https://github.com/open-telemetry/opentelemetry-js/blob/0229434cb5a3179f63c021105f36270ae7897929/experimental/packages/opentelemetry-sdk-node/src/sdk.ts#L398\n */\nexport function shutdownAzureMonitor(): Promise<void> {\n browserSdkLoader?.dispose();\n return sdk?.shutdown();\n}\n\n/**\n * Get the internal SDK instance for testing purposes\n * @internal\n */\n// eslint-disable-next-line no-underscore-dangle\nexport function _getSdkInstance(): NodeSDK | undefined {\n return sdk;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/metrics/handler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,WAAW,EACZ,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,6BAA6B,EAC9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAiDxE;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAC3C,OAAO,CAAC,oBAAoB,CAAC,CAA4B;IACzD,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAgB;IAE9B;;;;OAIG;gBACS,MAAM,EAAE,cAAc;IAmD3B,eAAe,IAAI,6BAA6B;IAIhD,QAAQ,IAAI,WAAW,EAAE;IAIzB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIrC,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAMpC,SAAS,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAM/C;;OAEG;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/metrics/handler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,WAAW,EACZ,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAGL,6BAA6B,EAC9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAiDxE;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,aAAa,CAAgC;IACrD,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAC3C,OAAO,CAAC,oBAAoB,CAAC,CAA4B;IACzD,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,MAAM,CAAgB;IAE9B;;;;OAIG;gBACS,MAAM,EAAE,cAAc;IAmD3B,eAAe,IAAI,6BAA6B;IAIhD,QAAQ,IAAI,WAAW,EAAE;IAIzB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIrC,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAMpC,SAAS,CAAC,SAAS,EAAE,YAAY,GAAG,IAAI;IAM/C;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAKvC"}
|
|
@@ -117,11 +117,10 @@ export class MetricHandler {
|
|
|
117
117
|
/**
|
|
118
118
|
* Shutdown handler
|
|
119
119
|
*/
|
|
120
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
121
120
|
async shutdown() {
|
|
122
121
|
this._standardMetrics?.shutdown();
|
|
123
|
-
this._liveMetrics?.shutdown();
|
|
124
|
-
this._performanceCounters?.shutdown();
|
|
122
|
+
await this._liveMetrics?.shutdown();
|
|
123
|
+
await this._performanceCounters?.shutdown();
|
|
125
124
|
}
|
|
126
125
|
}
|
|
127
126
|
//# sourceMappingURL=handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/metrics/handler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AzureMonitorMetricExporter } from \"@azure/monitor-opentelemetry-exporter\";\nimport type {\n AggregationOption,\n PeriodicExportingMetricReaderOptions,\n ViewOptions,\n} from \"@opentelemetry/sdk-metrics\";\nimport {\n AggregationType,\n InstrumentType,\n PeriodicExportingMetricReader,\n} from \"@opentelemetry/sdk-metrics\";\nimport type { SdkLogRecord } from \"@opentelemetry/sdk-logs\";\nimport type { InternalConfig } from \"../shared/config.js\";\nimport { StandardMetrics } from \"./standardMetrics.js\";\nimport type { ReadableSpan, Span } from \"@opentelemetry/sdk-trace-base\";\nimport { APPLICATION_INSIGHTS_NO_STANDARD_METRICS, HISTOGRAM_AGGREGATION_MAP } from \"./types.js\";\nimport { LiveMetrics } from \"./quickpulse/liveMetrics.js\";\nimport { PerformanceCounterMetrics } from \"./performanceCounters.js\";\nimport { Logger } from \"../shared/logging/index.js\";\n\ntype MetricExporterOptions = ConstructorParameters<typeof AzureMonitorMetricExporter>[0];\n\nconst DEFAULT_HISTOGRAM_AGGREGATION_ENV_VAR =\n \"OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION\";\n\nfunction resolveHistogramAggregationFromEnv(): AggregationOption | undefined {\n const envValue = process.env[DEFAULT_HISTOGRAM_AGGREGATION_ENV_VAR];\n if (!envValue) {\n return undefined;\n }\n\n const normalized = envValue.trim().toLowerCase();\n const aggregation = HISTOGRAM_AGGREGATION_MAP[normalized];\n if (aggregation) {\n return aggregation;\n }\n\n const validValues = Object.keys(HISTOGRAM_AGGREGATION_MAP)\n .map((v) => `'${v}'`)\n .join(\" and \");\n Logger.getInstance().warn(\n `${DEFAULT_HISTOGRAM_AGGREGATION_ENV_VAR} has unsupported value '${envValue}'. Supported values are ${validValues}.`,\n );\n return undefined;\n}\n\nclass AzureMonitorMetricExporterWithAggregation extends AzureMonitorMetricExporter {\n private _histogramAggregation?: AggregationOption;\n\n constructor(options: MetricExporterOptions, histogramAggregation?: AggregationOption) {\n super(options);\n this._histogramAggregation = histogramAggregation;\n }\n\n public selectAggregation(instrumentType: InstrumentType): AggregationOption {\n if (instrumentType === InstrumentType.HISTOGRAM && this._histogramAggregation) {\n return this._histogramAggregation;\n }\n\n return { type: AggregationType.DEFAULT };\n }\n}\n\n/**\n * Azure Monitor OpenTelemetry Metric Handler\n */\nexport class MetricHandler {\n private _azureExporter: AzureMonitorMetricExporter;\n private _metricReader: PeriodicExportingMetricReader;\n private _standardMetrics?: StandardMetrics;\n private _performanceCounters?: PerformanceCounterMetrics;\n private _liveMetrics?: LiveMetrics;\n private _config: InternalConfig;\n private _views: ViewOptions[];\n\n /**\n * Initializes a new instance of the MetricHandler class.\n * @param config - Distro configuration.\n * @param options - Metric Handler options.\n */\n constructor(config: InternalConfig) {\n const defaultInterval = 60000;\n this._config = config;\n // Adding Views of instrumentations will allow customer to add Metric Readers after, and get access to previously created metrics using the views shared state\n this._views = [];\n if (config.instrumentationOptions.azureSdk?.enabled) {\n this._views.push({ meterName: \"@azure/opentelemetry-instrumentation-azure-sdk\" });\n }\n if (config.instrumentationOptions.http?.enabled) {\n this._views.push({ meterName: \"@azure/opentelemetry-instrumentation-http\" });\n }\n if (config.instrumentationOptions.mongoDb?.enabled) {\n this._views.push({ meterName: \"@azure/opentelemetry-instrumentation-mongodb\" });\n }\n if (config.instrumentationOptions.mySql?.enabled) {\n this._views.push({ meterName: \"@opentelemetry/instrumentation-mysql\" });\n }\n if (config.instrumentationOptions.postgreSql?.enabled) {\n this._views.push({ meterName: \"@opentelemetry/instrumentation-pg\" });\n }\n if (\n config.instrumentationOptions.redis?.enabled ||\n config.instrumentationOptions.redis4?.enabled\n ) {\n this._views.push({ meterName: \"@opentelemetry/instrumentation-redis\" });\n }\n const histogramAggregation = resolveHistogramAggregationFromEnv();\n this._azureExporter = new AzureMonitorMetricExporterWithAggregation(\n this._config.azureMonitorExporterOptions,\n histogramAggregation,\n );\n const metricReaderOptions: PeriodicExportingMetricReaderOptions = {\n exporter: this._azureExporter as any,\n exportIntervalMillis: this._config.metricExportIntervalMillis || defaultInterval,\n };\n this._metricReader = new PeriodicExportingMetricReader(metricReaderOptions);\n\n if (\n this._config.enableStandardMetrics &&\n !process.env[APPLICATION_INSIGHTS_NO_STANDARD_METRICS]\n ) {\n this._standardMetrics = new StandardMetrics(this._config);\n }\n if (this._config.enableLiveMetrics) {\n this._liveMetrics = new LiveMetrics(this._config);\n }\n if (this._config.enablePerformanceCounters) {\n this._performanceCounters = new PerformanceCounterMetrics(this._config);\n }\n }\n\n public getMetricReader(): PeriodicExportingMetricReader {\n return this._metricReader;\n }\n\n public getViews(): ViewOptions[] {\n return this._views;\n }\n\n public markSpanAsProcessed(span: Span): void {\n this._standardMetrics?.markSpanAsProcessed(span);\n }\n\n public recordSpan(span: ReadableSpan): void {\n this._standardMetrics?.recordSpan(span);\n this._liveMetrics?.recordSpan(span);\n this._performanceCounters?.recordSpan(span);\n }\n\n public recordLog(logRecord: SdkLogRecord): void {\n this._standardMetrics?.recordLog(logRecord);\n this._liveMetrics?.recordLog(logRecord);\n this._performanceCounters?.recordLog(logRecord);\n }\n\n /**\n * Shutdown handler\n */\n // eslint-disable-next-line @typescript-eslint/require-await\n public async shutdown(): Promise<void> {\n this._standardMetrics?.shutdown();\n this._liveMetrics?.shutdown();\n this._performanceCounters?.shutdown();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/metrics/handler.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { AzureMonitorMetricExporter } from \"@azure/monitor-opentelemetry-exporter\";\nimport type {\n AggregationOption,\n PeriodicExportingMetricReaderOptions,\n ViewOptions,\n} from \"@opentelemetry/sdk-metrics\";\nimport {\n AggregationType,\n InstrumentType,\n PeriodicExportingMetricReader,\n} from \"@opentelemetry/sdk-metrics\";\nimport type { SdkLogRecord } from \"@opentelemetry/sdk-logs\";\nimport type { InternalConfig } from \"../shared/config.js\";\nimport { StandardMetrics } from \"./standardMetrics.js\";\nimport type { ReadableSpan, Span } from \"@opentelemetry/sdk-trace-base\";\nimport { APPLICATION_INSIGHTS_NO_STANDARD_METRICS, HISTOGRAM_AGGREGATION_MAP } from \"./types.js\";\nimport { LiveMetrics } from \"./quickpulse/liveMetrics.js\";\nimport { PerformanceCounterMetrics } from \"./performanceCounters.js\";\nimport { Logger } from \"../shared/logging/index.js\";\n\ntype MetricExporterOptions = ConstructorParameters<typeof AzureMonitorMetricExporter>[0];\n\nconst DEFAULT_HISTOGRAM_AGGREGATION_ENV_VAR =\n \"OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION\";\n\nfunction resolveHistogramAggregationFromEnv(): AggregationOption | undefined {\n const envValue = process.env[DEFAULT_HISTOGRAM_AGGREGATION_ENV_VAR];\n if (!envValue) {\n return undefined;\n }\n\n const normalized = envValue.trim().toLowerCase();\n const aggregation = HISTOGRAM_AGGREGATION_MAP[normalized];\n if (aggregation) {\n return aggregation;\n }\n\n const validValues = Object.keys(HISTOGRAM_AGGREGATION_MAP)\n .map((v) => `'${v}'`)\n .join(\" and \");\n Logger.getInstance().warn(\n `${DEFAULT_HISTOGRAM_AGGREGATION_ENV_VAR} has unsupported value '${envValue}'. Supported values are ${validValues}.`,\n );\n return undefined;\n}\n\nclass AzureMonitorMetricExporterWithAggregation extends AzureMonitorMetricExporter {\n private _histogramAggregation?: AggregationOption;\n\n constructor(options: MetricExporterOptions, histogramAggregation?: AggregationOption) {\n super(options);\n this._histogramAggregation = histogramAggregation;\n }\n\n public selectAggregation(instrumentType: InstrumentType): AggregationOption {\n if (instrumentType === InstrumentType.HISTOGRAM && this._histogramAggregation) {\n return this._histogramAggregation;\n }\n\n return { type: AggregationType.DEFAULT };\n }\n}\n\n/**\n * Azure Monitor OpenTelemetry Metric Handler\n */\nexport class MetricHandler {\n private _azureExporter: AzureMonitorMetricExporter;\n private _metricReader: PeriodicExportingMetricReader;\n private _standardMetrics?: StandardMetrics;\n private _performanceCounters?: PerformanceCounterMetrics;\n private _liveMetrics?: LiveMetrics;\n private _config: InternalConfig;\n private _views: ViewOptions[];\n\n /**\n * Initializes a new instance of the MetricHandler class.\n * @param config - Distro configuration.\n * @param options - Metric Handler options.\n */\n constructor(config: InternalConfig) {\n const defaultInterval = 60000;\n this._config = config;\n // Adding Views of instrumentations will allow customer to add Metric Readers after, and get access to previously created metrics using the views shared state\n this._views = [];\n if (config.instrumentationOptions.azureSdk?.enabled) {\n this._views.push({ meterName: \"@azure/opentelemetry-instrumentation-azure-sdk\" });\n }\n if (config.instrumentationOptions.http?.enabled) {\n this._views.push({ meterName: \"@azure/opentelemetry-instrumentation-http\" });\n }\n if (config.instrumentationOptions.mongoDb?.enabled) {\n this._views.push({ meterName: \"@azure/opentelemetry-instrumentation-mongodb\" });\n }\n if (config.instrumentationOptions.mySql?.enabled) {\n this._views.push({ meterName: \"@opentelemetry/instrumentation-mysql\" });\n }\n if (config.instrumentationOptions.postgreSql?.enabled) {\n this._views.push({ meterName: \"@opentelemetry/instrumentation-pg\" });\n }\n if (\n config.instrumentationOptions.redis?.enabled ||\n config.instrumentationOptions.redis4?.enabled\n ) {\n this._views.push({ meterName: \"@opentelemetry/instrumentation-redis\" });\n }\n const histogramAggregation = resolveHistogramAggregationFromEnv();\n this._azureExporter = new AzureMonitorMetricExporterWithAggregation(\n this._config.azureMonitorExporterOptions,\n histogramAggregation,\n );\n const metricReaderOptions: PeriodicExportingMetricReaderOptions = {\n exporter: this._azureExporter,\n exportIntervalMillis: this._config.metricExportIntervalMillis || defaultInterval,\n };\n this._metricReader = new PeriodicExportingMetricReader(metricReaderOptions);\n\n if (\n this._config.enableStandardMetrics &&\n !process.env[APPLICATION_INSIGHTS_NO_STANDARD_METRICS]\n ) {\n this._standardMetrics = new StandardMetrics(this._config);\n }\n if (this._config.enableLiveMetrics) {\n this._liveMetrics = new LiveMetrics(this._config);\n }\n if (this._config.enablePerformanceCounters) {\n this._performanceCounters = new PerformanceCounterMetrics(this._config);\n }\n }\n\n public getMetricReader(): PeriodicExportingMetricReader {\n return this._metricReader;\n }\n\n public getViews(): ViewOptions[] {\n return this._views;\n }\n\n public markSpanAsProcessed(span: Span): void {\n this._standardMetrics?.markSpanAsProcessed(span);\n }\n\n public recordSpan(span: ReadableSpan): void {\n this._standardMetrics?.recordSpan(span);\n this._liveMetrics?.recordSpan(span);\n this._performanceCounters?.recordSpan(span);\n }\n\n public recordLog(logRecord: SdkLogRecord): void {\n this._standardMetrics?.recordLog(logRecord);\n this._liveMetrics?.recordLog(logRecord);\n this._performanceCounters?.recordLog(logRecord);\n }\n\n /**\n * Shutdown handler\n */\n public async shutdown(): Promise<void> {\n this._standardMetrics?.shutdown();\n await this._liveMetrics?.shutdown();\n await this._performanceCounters?.shutdown();\n }\n}\n"]}
|
|
@@ -41,6 +41,16 @@ export declare class QuickpulseSender {
|
|
|
41
41
|
* @internal
|
|
42
42
|
*/
|
|
43
43
|
publish(optionalParams: PublishOptionalParams): Promise<QuickpulseResponse | undefined>;
|
|
44
|
+
/**
|
|
45
|
+
* Apply a server-issued Live Metrics redirect (`x-ms-qps-service-endpoint-redirect-v2`) by
|
|
46
|
+
* re-pointing the underlying client at the new host.
|
|
47
|
+
*
|
|
48
|
+
* Cross-origin redirects are refused (no state mutated) when the target is neither the configured
|
|
49
|
+
* Live Metrics host nor under a known Azure Monitor ingestion domain suffix. Refusing them is
|
|
50
|
+
* required to prevent an attacker-controlled redirect from causing the bearer auth policy to
|
|
51
|
+
* attach a freshly-signed AAD token (scope `https://monitor.azure.com/.default`) — and the
|
|
52
|
+
* telemetry body — to a foreign host on the next ping/publish call.
|
|
53
|
+
*/
|
|
44
54
|
handlePermanentRedirect(location: string | undefined): void;
|
|
45
55
|
}
|
|
46
56
|
//# sourceMappingURL=sender.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../../../../src/metrics/quickpulse/export/sender.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EACV,0BAA0B,EAC1B,qBAAqB,EAErB,2BAA2B,EAC5B,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../../../../src/metrics/quickpulse/export/sender.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EACV,0BAA0B,EAC1B,qBAAqB,EAErB,2BAA2B,EAC5B,MAAM,6BAA6B,CAAC;AAMrC;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,2BAA2B;IACrE,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,0BAA0B;IAC1B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,6CAA6C;IAC7C,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C,yCAAyC;IACzC,+BAA+B,CAAC,EAAE,MAAM,CAAC;CAC1C;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,gBAAgB,CAAW;gBAEvB,OAAO,EAAE;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,UAAU,CAAC,EAAE,eAAe,CAAC;QAC7B,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;KACtC;IAyBD,OAAO,CAAC,sBAAsB;IAO9B;;;OAGG;IACG,YAAY,CAChB,cAAc,EAAE,0BAA0B,GACzC,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;IAuB1C;;;OAGG;IACG,OAAO,CAAC,cAAc,EAAE,qBAAqB,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC;IAqB7F;;;;;;;;;OASG;IACH,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAkC5D"}
|
|
@@ -4,6 +4,7 @@ import url from "url";
|
|
|
4
4
|
import { redirectPolicyName } from "@azure/core-rest-pipeline";
|
|
5
5
|
import { diag } from "@opentelemetry/api";
|
|
6
6
|
import { QuickpulseClient } from "../../../generated/index.js";
|
|
7
|
+
import { isSameRegisteredDomain } from "../redirectUtils.js";
|
|
7
8
|
const applicationInsightsResource = "https://monitor.azure.com/.default";
|
|
8
9
|
/**
|
|
9
10
|
* Quickpulse sender class
|
|
@@ -95,17 +96,45 @@ export class QuickpulseSender {
|
|
|
95
96
|
}
|
|
96
97
|
return;
|
|
97
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Apply a server-issued Live Metrics redirect (`x-ms-qps-service-endpoint-redirect-v2`) by
|
|
101
|
+
* re-pointing the underlying client at the new host.
|
|
102
|
+
*
|
|
103
|
+
* Cross-origin redirects are refused (no state mutated) when the target is neither the configured
|
|
104
|
+
* Live Metrics host nor under a known Azure Monitor ingestion domain suffix. Refusing them is
|
|
105
|
+
* required to prevent an attacker-controlled redirect from causing the bearer auth policy to
|
|
106
|
+
* attach a freshly-signed AAD token (scope `https://monitor.azure.com/.default`) — and the
|
|
107
|
+
* telemetry body — to a foreign host on the next ping/publish call.
|
|
108
|
+
*/
|
|
98
109
|
handlePermanentRedirect(location) {
|
|
99
110
|
if (location) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
let locUrl;
|
|
112
|
+
try {
|
|
113
|
+
locUrl = new url.URL(location);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (!locUrl.host) {
|
|
119
|
+
return;
|
|
108
120
|
}
|
|
121
|
+
let currentHost = "";
|
|
122
|
+
try {
|
|
123
|
+
currentHost = new url.URL(this.endpointUrl).host;
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
currentHost = "";
|
|
127
|
+
}
|
|
128
|
+
if (!isSameRegisteredDomain(currentHost, locUrl.host)) {
|
|
129
|
+
diag.error(`Refusing cross-origin Live Metrics redirect to https://${locUrl.host}: target is neither the configured endpoint host nor under a known Azure Monitor ingestion domain.`);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
this.endpointUrl = "https://" + locUrl.host;
|
|
133
|
+
// Recreate the client so subsequent requests use the new endpoint
|
|
134
|
+
this.quickpulseClient = this.createQuickpulseClient({
|
|
135
|
+
endpoint: this.endpointUrl,
|
|
136
|
+
credentials: { scopes: this.credentialScopes },
|
|
137
|
+
});
|
|
109
138
|
}
|
|
110
139
|
}
|
|
111
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sender.js","sourceRoot":"","sources":["../../../../../src/metrics/quickpulse/export/sender.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport url from \"url\";\nimport type { RestError } from \"@azure/core-rest-pipeline\";\nimport { redirectPolicyName } from \"@azure/core-rest-pipeline\";\nimport type { TokenCredential } from \"@azure/core-auth\";\nimport { diag } from \"@opentelemetry/api\";\nimport type {\n IsSubscribedOptionalParams,\n PublishOptionalParams,\n QuickpulseClientOptionalParams,\n CollectionConfigurationInfo,\n} from \"../../../generated/index.js\";\nimport { QuickpulseClient } from \"../../../generated/index.js\";\n\nconst applicationInsightsResource = \"https://monitor.azure.com/.default\";\n\n/**\n * Response type that includes the body and response headers from the Live Metrics service.\n * @internal\n */\nexport interface QuickpulseResponse extends CollectionConfigurationInfo {\n /** Whether the instrumentation key is subscribed. */\n xMsQpsSubscribed?: string;\n /** Configuration ETag. */\n xMsQpsConfigurationEtag?: string;\n /** Polling interval hint (only for ping). */\n xMsQpsServicePollingIntervalHint?: string;\n /** Endpoint redirect (only for ping). */\n xMsQpsServiceEndpointRedirectV2?: string;\n}\n\n/**\n * Quickpulse sender class\n * @internal\n */\nexport class QuickpulseSender {\n private quickpulseClient: QuickpulseClient;\n private instrumentationKey: string;\n private endpointUrl: string;\n private credential: TokenCredential;\n private credentialScopes: string[];\n\n constructor(options: {\n endpointUrl: string;\n instrumentationKey: string;\n credential?: TokenCredential;\n credentialScopes?: string | string[];\n }) {\n // Build endpoint using provided configuration or default values\n this.endpointUrl = options.endpointUrl;\n const clientOptions: QuickpulseClientOptionalParams = {\n endpoint: this.endpointUrl,\n };\n\n this.instrumentationKey = options.instrumentationKey;\n this.credential = options.credential as TokenCredential;\n\n // Configure credential scopes\n if (options.credentialScopes) {\n this.credentialScopes = Array.isArray(options.credentialScopes)\n ? options.credentialScopes\n : [options.credentialScopes];\n } else {\n this.credentialScopes = [applicationInsightsResource];\n }\n if (options.credential) {\n clientOptions.credentials = { scopes: this.credentialScopes };\n }\n\n this.quickpulseClient = this.createQuickpulseClient(clientOptions);\n }\n\n private createQuickpulseClient(clientOptions: QuickpulseClientOptionalParams): QuickpulseClient {\n const client = new QuickpulseClient(this.credential, clientOptions);\n // Handle redirects in HTTP Sender\n client.pipeline.removePolicy({ name: redirectPolicyName });\n return client;\n }\n\n /**\n * isSubscribed Quickpulse service\n * @internal\n */\n async isSubscribed(\n optionalParams: IsSubscribedOptionalParams,\n ): Promise<QuickpulseResponse | undefined> {\n try {\n let responseHeaders: Record<string, string> = {};\n const body = await this.quickpulseClient.isSubscribed(this.instrumentationKey, {\n ...optionalParams,\n onResponse: (rawResponse) => {\n responseHeaders = rawResponse.headers.toJSON();\n },\n });\n return {\n ...body,\n xMsQpsSubscribed: responseHeaders[\"x-ms-qps-subscribed\"],\n xMsQpsConfigurationEtag: responseHeaders[\"x-ms-qps-configuration-etag\"],\n xMsQpsServicePollingIntervalHint: responseHeaders[\"x-ms-qps-service-polling-interval-hint\"],\n xMsQpsServiceEndpointRedirectV2: responseHeaders[\"x-ms-qps-service-endpoint-redirect-v2\"],\n };\n } catch (error: any) {\n const restError = error as RestError;\n diag.info(\"Failed to ping Quickpulse service\", restError.message);\n }\n return;\n }\n\n /**\n * publish Quickpulse service\n * @internal\n */\n async publish(optionalParams: PublishOptionalParams): Promise<QuickpulseResponse | undefined> {\n try {\n let responseHeaders: Record<string, string> = {};\n const body = await this.quickpulseClient.publish(this.instrumentationKey, {\n ...optionalParams,\n onResponse: (rawResponse) => {\n responseHeaders = rawResponse.headers.toJSON();\n },\n });\n return {\n ...body,\n xMsQpsSubscribed: responseHeaders[\"x-ms-qps-subscribed\"],\n xMsQpsConfigurationEtag: responseHeaders[\"x-ms-qps-configuration-etag\"],\n };\n } catch (error: any) {\n const restError = error as RestError;\n diag.warn(\"Failed to post Quickpulse service\", restError.message);\n }\n return;\n }\n\n handlePermanentRedirect(location: string | undefined): void {\n if (location) {\n const locUrl = new url.URL(location);\n if (locUrl && locUrl.host) {\n this.endpointUrl = \"https://\" + locUrl.host;\n // Recreate the client so subsequent requests use the new endpoint\n this.quickpulseClient = this.createQuickpulseClient({\n endpoint: this.endpointUrl,\n credentials: { scopes: this.credentialScopes },\n });\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sender.js","sourceRoot":"","sources":["../../../../../src/metrics/quickpulse/export/sender.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport url from \"url\";\nimport type { RestError } from \"@azure/core-rest-pipeline\";\nimport { redirectPolicyName } from \"@azure/core-rest-pipeline\";\nimport type { TokenCredential } from \"@azure/core-auth\";\nimport { diag } from \"@opentelemetry/api\";\nimport type {\n IsSubscribedOptionalParams,\n PublishOptionalParams,\n QuickpulseClientOptionalParams,\n CollectionConfigurationInfo,\n} from \"../../../generated/index.js\";\nimport { QuickpulseClient } from \"../../../generated/index.js\";\nimport { isSameRegisteredDomain } from \"../redirectUtils.js\";\n\nconst applicationInsightsResource = \"https://monitor.azure.com/.default\";\n\n/**\n * Response type that includes the body and response headers from the Live Metrics service.\n * @internal\n */\nexport interface QuickpulseResponse extends CollectionConfigurationInfo {\n /** Whether the instrumentation key is subscribed. */\n xMsQpsSubscribed?: string;\n /** Configuration ETag. */\n xMsQpsConfigurationEtag?: string;\n /** Polling interval hint (only for ping). */\n xMsQpsServicePollingIntervalHint?: string;\n /** Endpoint redirect (only for ping). */\n xMsQpsServiceEndpointRedirectV2?: string;\n}\n\n/**\n * Quickpulse sender class\n * @internal\n */\nexport class QuickpulseSender {\n private quickpulseClient: QuickpulseClient;\n private instrumentationKey: string;\n private endpointUrl: string;\n private credential: TokenCredential;\n private credentialScopes: string[];\n\n constructor(options: {\n endpointUrl: string;\n instrumentationKey: string;\n credential?: TokenCredential;\n credentialScopes?: string | string[];\n }) {\n // Build endpoint using provided configuration or default values\n this.endpointUrl = options.endpointUrl;\n const clientOptions: QuickpulseClientOptionalParams = {\n endpoint: this.endpointUrl,\n };\n\n this.instrumentationKey = options.instrumentationKey;\n this.credential = options.credential as TokenCredential;\n\n // Configure credential scopes\n if (options.credentialScopes) {\n this.credentialScopes = Array.isArray(options.credentialScopes)\n ? options.credentialScopes\n : [options.credentialScopes];\n } else {\n this.credentialScopes = [applicationInsightsResource];\n }\n if (options.credential) {\n clientOptions.credentials = { scopes: this.credentialScopes };\n }\n\n this.quickpulseClient = this.createQuickpulseClient(clientOptions);\n }\n\n private createQuickpulseClient(clientOptions: QuickpulseClientOptionalParams): QuickpulseClient {\n const client = new QuickpulseClient(this.credential, clientOptions);\n // Handle redirects in HTTP Sender\n client.pipeline.removePolicy({ name: redirectPolicyName });\n return client;\n }\n\n /**\n * isSubscribed Quickpulse service\n * @internal\n */\n async isSubscribed(\n optionalParams: IsSubscribedOptionalParams,\n ): Promise<QuickpulseResponse | undefined> {\n try {\n let responseHeaders: Record<string, string> = {};\n const body = await this.quickpulseClient.isSubscribed(this.instrumentationKey, {\n ...optionalParams,\n onResponse: (rawResponse) => {\n responseHeaders = rawResponse.headers.toJSON();\n },\n });\n return {\n ...body,\n xMsQpsSubscribed: responseHeaders[\"x-ms-qps-subscribed\"],\n xMsQpsConfigurationEtag: responseHeaders[\"x-ms-qps-configuration-etag\"],\n xMsQpsServicePollingIntervalHint: responseHeaders[\"x-ms-qps-service-polling-interval-hint\"],\n xMsQpsServiceEndpointRedirectV2: responseHeaders[\"x-ms-qps-service-endpoint-redirect-v2\"],\n };\n } catch (error: any) {\n const restError = error as RestError;\n diag.info(\"Failed to ping Quickpulse service\", restError.message);\n }\n return;\n }\n\n /**\n * publish Quickpulse service\n * @internal\n */\n async publish(optionalParams: PublishOptionalParams): Promise<QuickpulseResponse | undefined> {\n try {\n let responseHeaders: Record<string, string> = {};\n const body = await this.quickpulseClient.publish(this.instrumentationKey, {\n ...optionalParams,\n onResponse: (rawResponse) => {\n responseHeaders = rawResponse.headers.toJSON();\n },\n });\n return {\n ...body,\n xMsQpsSubscribed: responseHeaders[\"x-ms-qps-subscribed\"],\n xMsQpsConfigurationEtag: responseHeaders[\"x-ms-qps-configuration-etag\"],\n };\n } catch (error: any) {\n const restError = error as RestError;\n diag.warn(\"Failed to post Quickpulse service\", restError.message);\n }\n return;\n }\n\n /**\n * Apply a server-issued Live Metrics redirect (`x-ms-qps-service-endpoint-redirect-v2`) by\n * re-pointing the underlying client at the new host.\n *\n * Cross-origin redirects are refused (no state mutated) when the target is neither the configured\n * Live Metrics host nor under a known Azure Monitor ingestion domain suffix. Refusing them is\n * required to prevent an attacker-controlled redirect from causing the bearer auth policy to\n * attach a freshly-signed AAD token (scope `https://monitor.azure.com/.default`) — and the\n * telemetry body — to a foreign host on the next ping/publish call.\n */\n handlePermanentRedirect(location: string | undefined): void {\n if (location) {\n let locUrl: url.URL;\n try {\n locUrl = new url.URL(location);\n } catch {\n return;\n }\n if (!locUrl.host) {\n return;\n }\n\n let currentHost = \"\";\n try {\n currentHost = new url.URL(this.endpointUrl).host;\n } catch {\n currentHost = \"\";\n }\n\n if (!isSameRegisteredDomain(currentHost, locUrl.host)) {\n diag.error(\n `Refusing cross-origin Live Metrics redirect to https://${locUrl.host}: target is neither the configured endpoint host nor under a known Azure Monitor ingestion domain.`,\n );\n return;\n }\n\n this.endpointUrl = \"https://\" + locUrl.host;\n // Recreate the client so subsequent requests use the new endpoint\n this.quickpulseClient = this.createQuickpulseClient({\n endpoint: this.endpointUrl,\n credentials: { scopes: this.credentialScopes },\n });\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../../../src/metrics/quickpulse/filtering/filter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EAEjB,0BAA0B,EAC3B,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAEV,aAAa,EAId,MAAM,aAAa,CAAC;AAUrB,qBAAa,MAAM;IACV,qCAAqC,CAC1C,0BAA0B,EAAE,0BAA0B,GACrD,IAAI;IAQA,kBAAkB,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO;IAetF,2BAA2B,CAChC,0BAA0B,EAAE,0BAA0B,EACtD,IAAI,EAAE,aAAa,GAClB,OAAO;IAUV,OAAO,CAAC,WAAW;IA4DnB,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../../../src/metrics/quickpulse/filtering/filter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EAEjB,0BAA0B,EAC3B,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAEV,aAAa,EAId,MAAM,aAAa,CAAC;AAUrB,qBAAa,MAAM;IACV,qCAAqC,CAC1C,0BAA0B,EAAE,0BAA0B,GACrD,IAAI;IAQA,kBAAkB,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO;IAetF,2BAA2B,CAChC,0BAA0B,EAAE,0BAA0B,EACtD,IAAI,EAAE,aAAa,GAClB,OAAO;IAUV,OAAO,CAAC,WAAW;IA4DnB,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,aAAa;CAoBtB"}
|
|
@@ -121,11 +121,8 @@ export class Filter {
|
|
|
121
121
|
}
|
|
122
122
|
checkCustomDimFilter(filter, data) {
|
|
123
123
|
const fieldName = filter.fieldName.replace("CustomDimensions.", "");
|
|
124
|
-
|
|
125
|
-
if (
|
|
126
|
-
value = data.CustomDimensions.get(fieldName);
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
124
|
+
const value = data.CustomDimensions.get(fieldName);
|
|
125
|
+
if (value === undefined) {
|
|
129
126
|
return false; // the asked for field is not present in the custom dimensions
|
|
130
127
|
}
|
|
131
128
|
return this.stringCompare(value, filter.comparand, filter.predicate);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../../../src/metrics/quickpulse/filtering/filter.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type {\n DerivedMetricInfo,\n FilterInfo,\n FilterConjunctionGroupInfo,\n} from \"../../../generated/index.js\";\nimport type {\n RequestData,\n TelemetryData,\n DependencyData,\n ExceptionData,\n TraceData,\n} from \"../types.js\";\nimport { KnownDependencyColumns, KnownRequestColumns } from \"../types.js\";\nimport {\n isRequestData,\n isDependencyData,\n isExceptionData,\n isTraceData,\n getMsFromFilterTimestampString,\n} from \"../utils.js\";\n\nexport class Filter {\n public renameExceptionFieldNamesForFiltering(\n filterConjunctionGroupInfo: FilterConjunctionGroupInfo,\n ): void {\n filterConjunctionGroupInfo.filters.forEach((filter) => {\n if (filter.fieldName.startsWith(\"Exception.\")) {\n filter.fieldName = filter.fieldName.replace(\"Exception.\", \"\");\n }\n });\n }\n\n public checkMetricFilters(derivedMetricInfo: DerivedMetricInfo, data: TelemetryData): boolean {\n if (derivedMetricInfo.filterGroups.length === 0) {\n // This should never happen - even when a user does not add filter pills to the derived metric,\n // the filterGroups array should have one filter group with an empty array of filters.\n return true;\n }\n // Haven't yet seen any case where there is more than one filter group in a derived metric info.\n // Just to be safe, handling the multiple filter conjunction group case as an or operation.\n let matched = false;\n derivedMetricInfo.filterGroups.forEach((filterConjunctionGroup) => {\n matched = matched || this.checkFilterConjunctionGroup(filterConjunctionGroup, data);\n });\n return matched;\n }\n\n public checkFilterConjunctionGroup(\n filterConjunctionGroupInfo: FilterConjunctionGroupInfo,\n data: TelemetryData,\n ): boolean {\n // All of the filters need to match for this to return true (and operation).\n for (const filter of filterConjunctionGroupInfo.filters) {\n if (!this.checkFilter(filter, data)) {\n return false;\n }\n }\n return true;\n }\n\n private checkFilter(filter: FilterInfo, data: TelemetryData): boolean {\n if (filter.fieldName === \"*\") {\n // Any field\n return this.checkAnyFieldFilter(filter, data);\n } else if (filter.fieldName.startsWith(\"CustomDimensions.\")) {\n return this.checkCustomDimFilter(filter, data);\n } else {\n let dataValue: string | number | boolean | Map<string, string>;\n // use filter.fieldname to get the property of data to query\n if (isRequestData(data)) {\n dataValue = data[filter.fieldName as keyof RequestData];\n } else if (isDependencyData(data)) {\n dataValue = data[filter.fieldName as keyof DependencyData];\n } else if (isExceptionData(data)) {\n dataValue = data[filter.fieldName as keyof ExceptionData];\n } else if (isTraceData(data)) {\n dataValue = data[filter.fieldName as keyof TraceData];\n } else {\n return false; // should not reach here\n }\n\n if (filter.fieldName === KnownRequestColumns.Success.toString()) {\n if (filter.predicate === \"Equal\") {\n return dataValue === (filter.comparand.toLowerCase() === \"true\");\n } else if (filter.predicate === \"NotEqual\") {\n return dataValue !== (filter.comparand.toLowerCase() === \"true\");\n }\n } else if (\n filter.fieldName === KnownDependencyColumns.ResultCode.toString() ||\n filter.fieldName === KnownRequestColumns.ResponseCode.toString() ||\n filter.fieldName === KnownDependencyColumns.Duration.toString()\n ) {\n const comparand: number =\n filter.fieldName === KnownDependencyColumns.Duration.toString()\n ? getMsFromFilterTimestampString(filter.comparand)\n : parseFloat(filter.comparand);\n switch (filter.predicate) {\n case \"Equal\":\n return dataValue === comparand;\n case \"NotEqual\":\n return dataValue !== comparand;\n case \"GreaterThan\":\n return (dataValue as number) > comparand;\n case \"GreaterThanOrEqual\":\n return (dataValue as number) >= comparand;\n case \"LessThan\":\n return (dataValue as number) < comparand;\n case \"LessThanOrEqual\":\n return (dataValue as number) <= comparand;\n default:\n return false;\n }\n } else {\n // string fields\n return this.stringCompare(dataValue as string, filter.comparand, filter.predicate);\n }\n }\n return false;\n }\n\n private checkAnyFieldFilter(filter: FilterInfo, data: TelemetryData): boolean {\n const properties: string[] = Object.keys(data);\n // At this point, the only predicates possible to pass in are Contains and DoesNotContain\n // At config validation time the predicate is checked to be one of these two.\n for (const property of properties) {\n if (property === \"CustomDimensions\") {\n for (const value of data.CustomDimensions.values()) {\n if (this.stringCompare(value, filter.comparand, filter.predicate)) {\n return true;\n }\n }\n } else {\n // @ts-expect-error - data can be any type of telemetry data and we know property is a valid key\n const value: string = String(data[property]);\n if (this.stringCompare(value, filter.comparand, filter.predicate)) {\n return true;\n }\n }\n }\n return false;\n }\n\n private checkCustomDimFilter(filter: FilterInfo, data: TelemetryData): boolean {\n const fieldName: string = filter.fieldName.replace(\"CustomDimensions.\", \"\");\n let value: string | undefined;\n if (data.CustomDimensions.has(fieldName)) {\n value = data.CustomDimensions.get(fieldName) as string;\n } else {\n return false; // the asked for field is not present in the custom dimensions\n }\n return this.stringCompare(value, filter.comparand, filter.predicate);\n }\n\n private stringCompare(dataValue: string, comparand: string, predicate: string): boolean {\n switch (predicate) {\n case \"Equal\":\n return dataValue === comparand;\n case \"NotEqual\":\n return dataValue !== comparand;\n case \"Contains\": {\n const lowerDataValue = dataValue.toLowerCase();\n const lowerComparand = comparand.toLowerCase();\n return lowerDataValue.includes(lowerComparand);\n }\n case \"DoesNotContain\": {\n const lowerDataValue = dataValue.toLowerCase();\n const lowerComparand = comparand.toLowerCase();\n return !lowerDataValue.includes(lowerComparand);\n }\n default:\n return false;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../../../../../src/metrics/quickpulse/filtering/filter.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type {\n DerivedMetricInfo,\n FilterInfo,\n FilterConjunctionGroupInfo,\n} from \"../../../generated/index.js\";\nimport type {\n RequestData,\n TelemetryData,\n DependencyData,\n ExceptionData,\n TraceData,\n} from \"../types.js\";\nimport { KnownDependencyColumns, KnownRequestColumns } from \"../types.js\";\nimport {\n isRequestData,\n isDependencyData,\n isExceptionData,\n isTraceData,\n getMsFromFilterTimestampString,\n} from \"../utils.js\";\n\nexport class Filter {\n public renameExceptionFieldNamesForFiltering(\n filterConjunctionGroupInfo: FilterConjunctionGroupInfo,\n ): void {\n filterConjunctionGroupInfo.filters.forEach((filter) => {\n if (filter.fieldName.startsWith(\"Exception.\")) {\n filter.fieldName = filter.fieldName.replace(\"Exception.\", \"\");\n }\n });\n }\n\n public checkMetricFilters(derivedMetricInfo: DerivedMetricInfo, data: TelemetryData): boolean {\n if (derivedMetricInfo.filterGroups.length === 0) {\n // This should never happen - even when a user does not add filter pills to the derived metric,\n // the filterGroups array should have one filter group with an empty array of filters.\n return true;\n }\n // Haven't yet seen any case where there is more than one filter group in a derived metric info.\n // Just to be safe, handling the multiple filter conjunction group case as an or operation.\n let matched = false;\n derivedMetricInfo.filterGroups.forEach((filterConjunctionGroup) => {\n matched = matched || this.checkFilterConjunctionGroup(filterConjunctionGroup, data);\n });\n return matched;\n }\n\n public checkFilterConjunctionGroup(\n filterConjunctionGroupInfo: FilterConjunctionGroupInfo,\n data: TelemetryData,\n ): boolean {\n // All of the filters need to match for this to return true (and operation).\n for (const filter of filterConjunctionGroupInfo.filters) {\n if (!this.checkFilter(filter, data)) {\n return false;\n }\n }\n return true;\n }\n\n private checkFilter(filter: FilterInfo, data: TelemetryData): boolean {\n if (filter.fieldName === \"*\") {\n // Any field\n return this.checkAnyFieldFilter(filter, data);\n } else if (filter.fieldName.startsWith(\"CustomDimensions.\")) {\n return this.checkCustomDimFilter(filter, data);\n } else {\n let dataValue: string | number | boolean | Map<string, string>;\n // use filter.fieldname to get the property of data to query\n if (isRequestData(data)) {\n dataValue = data[filter.fieldName as keyof RequestData];\n } else if (isDependencyData(data)) {\n dataValue = data[filter.fieldName as keyof DependencyData];\n } else if (isExceptionData(data)) {\n dataValue = data[filter.fieldName as keyof ExceptionData];\n } else if (isTraceData(data)) {\n dataValue = data[filter.fieldName as keyof TraceData];\n } else {\n return false; // should not reach here\n }\n\n if (filter.fieldName === KnownRequestColumns.Success.toString()) {\n if (filter.predicate === \"Equal\") {\n return dataValue === (filter.comparand.toLowerCase() === \"true\");\n } else if (filter.predicate === \"NotEqual\") {\n return dataValue !== (filter.comparand.toLowerCase() === \"true\");\n }\n } else if (\n filter.fieldName === KnownDependencyColumns.ResultCode.toString() ||\n filter.fieldName === KnownRequestColumns.ResponseCode.toString() ||\n filter.fieldName === KnownDependencyColumns.Duration.toString()\n ) {\n const comparand: number =\n filter.fieldName === KnownDependencyColumns.Duration.toString()\n ? getMsFromFilterTimestampString(filter.comparand)\n : parseFloat(filter.comparand);\n switch (filter.predicate) {\n case \"Equal\":\n return dataValue === comparand;\n case \"NotEqual\":\n return dataValue !== comparand;\n case \"GreaterThan\":\n return (dataValue as number) > comparand;\n case \"GreaterThanOrEqual\":\n return (dataValue as number) >= comparand;\n case \"LessThan\":\n return (dataValue as number) < comparand;\n case \"LessThanOrEqual\":\n return (dataValue as number) <= comparand;\n default:\n return false;\n }\n } else {\n // string fields\n return this.stringCompare(dataValue as string, filter.comparand, filter.predicate);\n }\n }\n return false;\n }\n\n private checkAnyFieldFilter(filter: FilterInfo, data: TelemetryData): boolean {\n const properties: string[] = Object.keys(data);\n // At this point, the only predicates possible to pass in are Contains and DoesNotContain\n // At config validation time the predicate is checked to be one of these two.\n for (const property of properties) {\n if (property === \"CustomDimensions\") {\n for (const value of data.CustomDimensions.values()) {\n if (this.stringCompare(value, filter.comparand, filter.predicate)) {\n return true;\n }\n }\n } else {\n // @ts-expect-error - data can be any type of telemetry data and we know property is a valid key\n const value: string = String(data[property]);\n if (this.stringCompare(value, filter.comparand, filter.predicate)) {\n return true;\n }\n }\n }\n return false;\n }\n\n private checkCustomDimFilter(filter: FilterInfo, data: TelemetryData): boolean {\n const fieldName: string = filter.fieldName.replace(\"CustomDimensions.\", \"\");\n const value = data.CustomDimensions.get(fieldName);\n if (value === undefined) {\n return false; // the asked for field is not present in the custom dimensions\n }\n return this.stringCompare(value, filter.comparand, filter.predicate);\n }\n\n private stringCompare(dataValue: string, comparand: string, predicate: string): boolean {\n switch (predicate) {\n case \"Equal\":\n return dataValue === comparand;\n case \"NotEqual\":\n return dataValue !== comparand;\n case \"Contains\": {\n const lowerDataValue = dataValue.toLowerCase();\n const lowerComparand = comparand.toLowerCase();\n return lowerDataValue.includes(lowerComparand);\n }\n case \"DoesNotContain\": {\n const lowerDataValue = dataValue.toLowerCase();\n const lowerComparand = comparand.toLowerCase();\n return !lowerDataValue.includes(lowerComparand);\n }\n default:\n return false;\n }\n }\n}\n"]}
|
|
@@ -28,6 +28,8 @@ export declare class LiveMetrics {
|
|
|
28
28
|
private quickpulseExporter;
|
|
29
29
|
private pingSender;
|
|
30
30
|
private isCollectingData;
|
|
31
|
+
private isDeactivating;
|
|
32
|
+
private deactivatingPromise;
|
|
31
33
|
private lastSuccessTime;
|
|
32
34
|
private handle;
|
|
33
35
|
private baseMonitoringDataPoint;
|
|
@@ -62,7 +64,7 @@ export declare class LiveMetrics {
|
|
|
62
64
|
* @param options - Standard Metrics options.
|
|
63
65
|
*/
|
|
64
66
|
constructor(config: InternalConfig);
|
|
65
|
-
shutdown(): void
|
|
67
|
+
shutdown(): Promise<void>;
|
|
66
68
|
private goQuickpulse;
|
|
67
69
|
private quickPulseDone;
|
|
68
70
|
activateMetrics(options?: {
|
|
@@ -71,7 +73,7 @@ export declare class LiveMetrics {
|
|
|
71
73
|
/**
|
|
72
74
|
* Deactivate metric collection
|
|
73
75
|
*/
|
|
74
|
-
deactivateMetrics(): void
|
|
76
|
+
deactivateMetrics(): Promise<void>;
|
|
75
77
|
/**
|
|
76
78
|
* Force flush Meter Provider.
|
|
77
79
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"liveMetrics.d.ts","sourceRoot":"","sources":["../../../../src/metrics/quickpulse/liveMetrics.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAiC,MAAM,4BAA4B,CAAC;AAC1F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG7D,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,+BAA+B,CAAC;AAE9E,OAAO,KAAK,EACV,eAAe,EAUhB,MAAM,0BAA0B,CAAC;AA6BlC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AAsB7E;;;GAGG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,YAAY,CAA4C;IAChE,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,oBAAoB,CAA8B;IAC1D,OAAO,CAAC,uBAAuB,CAA8B;IAC7D,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,sBAAsB,CAA8B;IAC5D,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,yBAAyB,CAA8B;IAC/D,OAAO,CAAC,yBAAyB,CAA8B;IAC/D,OAAO,CAAC,mCAAmC,CAA8B;IACzE,OAAO,CAAC,mBAAmB,CAA8B;IAEzD,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,kBAAkB,CAA2B;IACrD,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,gBAAgB,CAAU;IAClC,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,MAAM,CAAe;IAE7B,OAAO,CAAC,uBAAuB,CAAsB;IACrD,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,uBAAuB,CAAK;IACpC,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,0BAA0B,CAAK;IACvC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,mBAAmB,CAIzB;IACF,OAAO,CAAC,eAAe,CAA0D;IACjF,OAAO,CAAC,qBAAqB,CAA0D;IACvF,OAAO,CAAC,sBAAsB,CAI5B;IACF,OAAO,CAAC,kBAAkB,CAA0D;IACpF,OAAO,CAAC,wBAAwB,CAA0D;IAC1F,OAAO,CAAC,iBAAiB,CAA0D;IACnF,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,IAAI,CAAc;IAC1B,OAAO,CAAC,YAAY,CACwB;IAE5C,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,mBAAmB,CAA+C;IAC1E,OAAO,CAAC,uBAAuB,CAAgC;IAC/D,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,MAAM,CAAwB;IAEtC,OAAO,CAAC,uCAAuC,CAGjC;IACd;;;;OAIG;gBACS,MAAM,EAAE,cAAc;
|
|
1
|
+
{"version":3,"file":"liveMetrics.d.ts","sourceRoot":"","sources":["../../../../src/metrics/quickpulse/liveMetrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,6 +50,8 @@ export class LiveMetrics {
|
|
|
50
50
|
quickpulseExporter;
|
|
51
51
|
pingSender;
|
|
52
52
|
isCollectingData;
|
|
53
|
+
isDeactivating = false;
|
|
54
|
+
deactivatingPromise;
|
|
53
55
|
lastSuccessTime = Date.now();
|
|
54
56
|
handle;
|
|
55
57
|
// Monitoring data point with common properties
|
|
@@ -144,8 +146,15 @@ export class LiveMetrics {
|
|
|
144
146
|
this.lastCpuUsage = process.cpuUsage();
|
|
145
147
|
this.lastHrTime = process.hrtime.bigint();
|
|
146
148
|
}
|
|
147
|
-
shutdown() {
|
|
148
|
-
|
|
149
|
+
async shutdown() {
|
|
150
|
+
// Force collecting=false before tearing down so the shutdown's final
|
|
151
|
+
// force-flush export, if it fails, cannot trigger the deactivate/
|
|
152
|
+
// reactivate fallback in quickPulseDone(). Delegate to deactivateMetrics()
|
|
153
|
+
// which manages the in-flight deactivation promise so callers (including
|
|
154
|
+
// a concurrent failure-fallback in quickPulseDone) all observe the same
|
|
155
|
+
// completion and shutdown waits for any in-flight deactivation to finish.
|
|
156
|
+
this.isCollectingData = false;
|
|
157
|
+
await this.deactivateMetrics();
|
|
149
158
|
}
|
|
150
159
|
async goQuickpulse() {
|
|
151
160
|
if (!this.isCollectingData) {
|
|
@@ -172,7 +181,6 @@ export class LiveMetrics {
|
|
|
172
181
|
this.activateMetrics({ collectionInterval: this.postInterval });
|
|
173
182
|
}
|
|
174
183
|
}
|
|
175
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
176
184
|
async quickPulseDone(response) {
|
|
177
185
|
if (!response) {
|
|
178
186
|
if (!this.isCollectingData) {
|
|
@@ -182,9 +190,34 @@ export class LiveMetrics {
|
|
|
182
190
|
}
|
|
183
191
|
else {
|
|
184
192
|
if (Date.now() - this.lastSuccessTime >= MAX_POST_WAIT_TIME) {
|
|
193
|
+
// Re-entrancy guard: MeterProvider.shutdown() triggers a final
|
|
194
|
+
// force-flush export which, on failure, re-invokes this callback
|
|
195
|
+
// synchronously from inside the shutdown's export call. If a
|
|
196
|
+
// deactivation is already in flight, bail out — awaiting the
|
|
197
|
+
// in-flight promise here would deadlock the exporter's callback.
|
|
198
|
+
if (this.isDeactivating) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
185
201
|
this.postInterval = FALLBACK_INTERVAL;
|
|
186
|
-
|
|
187
|
-
|
|
202
|
+
try {
|
|
203
|
+
await this.deactivateMetrics();
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
// The exporter invokes postCallback without awaiting it, so a
|
|
207
|
+
// rejection here would surface as an unhandled rejection. Swallow
|
|
208
|
+
// and log so the failure path stays contained.
|
|
209
|
+
Logger.getInstance().warn("Failed to deactivate Live Metrics during failure fallback", error);
|
|
210
|
+
}
|
|
211
|
+
// Reset the success-time baseline so the FALLBACK_INTERVAL backoff
|
|
212
|
+
// can take effect before we consider deactivating again.
|
|
213
|
+
this.lastSuccessTime = Date.now();
|
|
214
|
+
// Re-check after the await: shutdown() may have run concurrently and
|
|
215
|
+
// flipped isCollectingData to false. Don't restart collection in
|
|
216
|
+
// that case — doing so would re-create the meterProvider after
|
|
217
|
+
// shutdown has begun.
|
|
218
|
+
if (this.isCollectingData) {
|
|
219
|
+
this.activateMetrics({ collectionInterval: this.postInterval });
|
|
220
|
+
}
|
|
188
221
|
}
|
|
189
222
|
}
|
|
190
223
|
}
|
|
@@ -200,7 +233,7 @@ export class LiveMetrics {
|
|
|
200
233
|
// If collecting was stoped
|
|
201
234
|
if (!this.isCollectingData && this.meterProvider) {
|
|
202
235
|
this.etag = "";
|
|
203
|
-
this.deactivateMetrics();
|
|
236
|
+
await this.deactivateMetrics();
|
|
204
237
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
205
238
|
this.handle = setTimeout(this.goQuickpulse.bind(this), this.pingInterval);
|
|
206
239
|
this.handle.unref();
|
|
@@ -294,16 +327,38 @@ export class LiveMetrics {
|
|
|
294
327
|
/**
|
|
295
328
|
* Deactivate metric collection
|
|
296
329
|
*/
|
|
297
|
-
deactivateMetrics() {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
this.
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
this.
|
|
330
|
+
async deactivateMetrics() {
|
|
331
|
+
// Coalesce concurrent deactivations: callers (shutdown(), the
|
|
332
|
+
// failure-fallback in quickPulseDone(), and the "unsubscribed" branch in
|
|
333
|
+
// goQuickpulse()) can all race. Return the in-flight promise so every
|
|
334
|
+
// caller awaits the same completion and the underlying meterProvider
|
|
335
|
+
// shutdown only runs once.
|
|
336
|
+
if (this.deactivatingPromise) {
|
|
337
|
+
return this.deactivatingPromise;
|
|
338
|
+
}
|
|
339
|
+
this.isDeactivating = true;
|
|
340
|
+
this.deactivatingPromise = (async () => {
|
|
341
|
+
try {
|
|
342
|
+
this.documents = [];
|
|
343
|
+
this.validDocumentFilterConjuctionGroupInfos.clear();
|
|
344
|
+
this.errorTracker.clearRunTimeErrors();
|
|
345
|
+
this.errorTracker.clearValidationTimeErrors();
|
|
346
|
+
this.validDerivedMetrics.clear();
|
|
347
|
+
this.derivedMetricProjection.clearProjectionMaps();
|
|
348
|
+
this.seenMetricIds.clear();
|
|
349
|
+
// Capture and clear the reference before awaiting shutdown so any
|
|
350
|
+
// re-entrant calls triggered by the shutdown's final force-flush
|
|
351
|
+
// export observe meterProvider as undefined and exit early.
|
|
352
|
+
const provider = this.meterProvider;
|
|
353
|
+
this.meterProvider = undefined;
|
|
354
|
+
await provider?.shutdown();
|
|
355
|
+
}
|
|
356
|
+
finally {
|
|
357
|
+
this.isDeactivating = false;
|
|
358
|
+
this.deactivatingPromise = undefined;
|
|
359
|
+
}
|
|
360
|
+
})();
|
|
361
|
+
return this.deactivatingPromise;
|
|
307
362
|
}
|
|
308
363
|
/**
|
|
309
364
|
* Force flush Meter Provider.
|