@azure/monitor-opentelemetry 1.18.1 → 1.19.0

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.
Files changed (137) hide show
  1. package/README.md +8 -1
  2. package/dist/commonjs/index.d.ts.map +1 -1
  3. package/dist/commonjs/index.js +20 -3
  4. package/dist/commonjs/index.js.map +1 -1
  5. package/dist/commonjs/logs/batchLogRecordProcessor.js +1 -1
  6. package/dist/commonjs/logs/batchLogRecordProcessor.js.map +1 -1
  7. package/dist/commonjs/logs/handler.d.ts +3 -0
  8. package/dist/commonjs/logs/handler.d.ts.map +1 -1
  9. package/dist/commonjs/logs/handler.js +22 -2
  10. package/dist/commonjs/logs/handler.js.map +1 -1
  11. package/dist/commonjs/metrics/handler.d.ts.map +1 -1
  12. package/dist/commonjs/metrics/handler.js +2 -3
  13. package/dist/commonjs/metrics/handler.js.map +1 -1
  14. package/dist/commonjs/metrics/quickpulse/credentialUtils.d.ts +16 -0
  15. package/dist/commonjs/metrics/quickpulse/credentialUtils.d.ts.map +1 -0
  16. package/dist/commonjs/metrics/quickpulse/credentialUtils.js +48 -0
  17. package/dist/commonjs/metrics/quickpulse/credentialUtils.js.map +1 -0
  18. package/dist/commonjs/metrics/quickpulse/export/sender.d.ts +10 -0
  19. package/dist/commonjs/metrics/quickpulse/export/sender.d.ts.map +1 -1
  20. package/dist/commonjs/metrics/quickpulse/export/sender.js +37 -8
  21. package/dist/commonjs/metrics/quickpulse/export/sender.js.map +1 -1
  22. package/dist/commonjs/metrics/quickpulse/filtering/filter.d.ts.map +1 -1
  23. package/dist/commonjs/metrics/quickpulse/filtering/filter.js +2 -5
  24. package/dist/commonjs/metrics/quickpulse/filtering/filter.js.map +1 -1
  25. package/dist/commonjs/metrics/quickpulse/liveMetrics.d.ts +4 -2
  26. package/dist/commonjs/metrics/quickpulse/liveMetrics.d.ts.map +1 -1
  27. package/dist/commonjs/metrics/quickpulse/liveMetrics.js +75 -18
  28. package/dist/commonjs/metrics/quickpulse/liveMetrics.js.map +1 -1
  29. package/dist/commonjs/metrics/quickpulse/redirectUtils.d.ts +28 -0
  30. package/dist/commonjs/metrics/quickpulse/redirectUtils.d.ts.map +1 -0
  31. package/dist/commonjs/metrics/quickpulse/redirectUtils.js +80 -0
  32. package/dist/commonjs/metrics/quickpulse/redirectUtils.js.map +1 -0
  33. package/dist/commonjs/metrics/quickpulse/utils.d.ts.map +1 -1
  34. package/dist/commonjs/metrics/quickpulse/utils.js.map +1 -1
  35. package/dist/commonjs/metrics/standardMetrics.js.map +1 -1
  36. package/dist/commonjs/shared/config.d.ts.map +1 -1
  37. package/dist/commonjs/shared/config.js +1 -0
  38. package/dist/commonjs/shared/config.js.map +1 -1
  39. package/dist/commonjs/shared/logging/diagFileConsoleLogger.d.ts +1 -0
  40. package/dist/commonjs/shared/logging/diagFileConsoleLogger.d.ts.map +1 -1
  41. package/dist/commonjs/shared/logging/diagFileConsoleLogger.js +13 -12
  42. package/dist/commonjs/shared/logging/diagFileConsoleLogger.js.map +1 -1
  43. package/dist/commonjs/traces/handler.d.ts +12 -0
  44. package/dist/commonjs/traces/handler.d.ts.map +1 -1
  45. package/dist/commonjs/traces/handler.js +30 -1
  46. package/dist/commonjs/traces/handler.js.map +1 -1
  47. package/dist/commonjs/tsdoc-metadata.json +1 -1
  48. package/dist/commonjs/types.d.ts +11 -1
  49. package/dist/commonjs/types.d.ts.map +1 -1
  50. package/dist/commonjs/types.js +47 -3
  51. package/dist/commonjs/types.js.map +1 -1
  52. package/dist/commonjs/utils/azureSdkTracingBridge.d.ts +18 -0
  53. package/dist/commonjs/utils/azureSdkTracingBridge.d.ts.map +1 -0
  54. package/dist/commonjs/utils/azureSdkTracingBridge.js +35 -0
  55. package/dist/commonjs/utils/azureSdkTracingBridge.js.map +1 -0
  56. package/dist/commonjs/utils/common.d.ts +10 -0
  57. package/dist/commonjs/utils/common.d.ts.map +1 -1
  58. package/dist/commonjs/utils/common.js +16 -0
  59. package/dist/commonjs/utils/common.js.map +1 -1
  60. package/dist/commonjs/utils/logUtils.d.ts +5 -0
  61. package/dist/commonjs/utils/logUtils.d.ts.map +1 -1
  62. package/dist/commonjs/utils/logUtils.js +8 -0
  63. package/dist/commonjs/utils/logUtils.js.map +1 -1
  64. package/dist/commonjs/utils/opentelemetryInstrumentationPatcher.d.ts.map +1 -1
  65. package/dist/commonjs/utils/opentelemetryInstrumentationPatcher.js +3 -2
  66. package/dist/commonjs/utils/opentelemetryInstrumentationPatcher.js.map +1 -1
  67. package/dist/commonjs/utils/statsbeat.d.ts.map +1 -1
  68. package/dist/commonjs/utils/statsbeat.js +35 -30
  69. package/dist/commonjs/utils/statsbeat.js.map +1 -1
  70. package/dist/esm/index.d.ts.map +1 -1
  71. package/dist/esm/index.js +20 -3
  72. package/dist/esm/index.js.map +1 -1
  73. package/dist/esm/logs/batchLogRecordProcessor.js +1 -1
  74. package/dist/esm/logs/batchLogRecordProcessor.js.map +1 -1
  75. package/dist/esm/logs/handler.d.ts +3 -0
  76. package/dist/esm/logs/handler.d.ts.map +1 -1
  77. package/dist/esm/logs/handler.js +23 -3
  78. package/dist/esm/logs/handler.js.map +1 -1
  79. package/dist/esm/metrics/handler.d.ts.map +1 -1
  80. package/dist/esm/metrics/handler.js +2 -3
  81. package/dist/esm/metrics/handler.js.map +1 -1
  82. package/dist/esm/metrics/quickpulse/credentialUtils.d.ts +16 -0
  83. package/dist/esm/metrics/quickpulse/credentialUtils.d.ts.map +1 -0
  84. package/dist/esm/metrics/quickpulse/credentialUtils.js +45 -0
  85. package/dist/esm/metrics/quickpulse/credentialUtils.js.map +1 -0
  86. package/dist/esm/metrics/quickpulse/export/sender.d.ts +10 -0
  87. package/dist/esm/metrics/quickpulse/export/sender.d.ts.map +1 -1
  88. package/dist/esm/metrics/quickpulse/export/sender.js +37 -8
  89. package/dist/esm/metrics/quickpulse/export/sender.js.map +1 -1
  90. package/dist/esm/metrics/quickpulse/filtering/filter.d.ts.map +1 -1
  91. package/dist/esm/metrics/quickpulse/filtering/filter.js +2 -5
  92. package/dist/esm/metrics/quickpulse/filtering/filter.js.map +1 -1
  93. package/dist/esm/metrics/quickpulse/liveMetrics.d.ts +4 -2
  94. package/dist/esm/metrics/quickpulse/liveMetrics.d.ts.map +1 -1
  95. package/dist/esm/metrics/quickpulse/liveMetrics.js +75 -18
  96. package/dist/esm/metrics/quickpulse/liveMetrics.js.map +1 -1
  97. package/dist/esm/metrics/quickpulse/redirectUtils.d.ts +28 -0
  98. package/dist/esm/metrics/quickpulse/redirectUtils.d.ts.map +1 -0
  99. package/dist/esm/metrics/quickpulse/redirectUtils.js +76 -0
  100. package/dist/esm/metrics/quickpulse/redirectUtils.js.map +1 -0
  101. package/dist/esm/metrics/quickpulse/utils.d.ts.map +1 -1
  102. package/dist/esm/metrics/quickpulse/utils.js.map +1 -1
  103. package/dist/esm/metrics/standardMetrics.js.map +1 -1
  104. package/dist/esm/shared/config.d.ts.map +1 -1
  105. package/dist/esm/shared/config.js +1 -0
  106. package/dist/esm/shared/config.js.map +1 -1
  107. package/dist/esm/shared/logging/diagFileConsoleLogger.d.ts +1 -0
  108. package/dist/esm/shared/logging/diagFileConsoleLogger.d.ts.map +1 -1
  109. package/dist/esm/shared/logging/diagFileConsoleLogger.js +13 -12
  110. package/dist/esm/shared/logging/diagFileConsoleLogger.js.map +1 -1
  111. package/dist/esm/traces/handler.d.ts +12 -0
  112. package/dist/esm/traces/handler.d.ts.map +1 -1
  113. package/dist/esm/traces/handler.js +29 -1
  114. package/dist/esm/traces/handler.js.map +1 -1
  115. package/dist/esm/types.d.ts +11 -1
  116. package/dist/esm/types.d.ts.map +1 -1
  117. package/dist/esm/types.js +46 -2
  118. package/dist/esm/types.js.map +1 -1
  119. package/dist/esm/utils/azureSdkTracingBridge.d.ts +18 -0
  120. package/dist/esm/utils/azureSdkTracingBridge.d.ts.map +1 -0
  121. package/dist/esm/utils/azureSdkTracingBridge.js +34 -0
  122. package/dist/esm/utils/azureSdkTracingBridge.js.map +1 -0
  123. package/dist/esm/utils/common.d.ts +10 -0
  124. package/dist/esm/utils/common.d.ts.map +1 -1
  125. package/dist/esm/utils/common.js +14 -0
  126. package/dist/esm/utils/common.js.map +1 -1
  127. package/dist/esm/utils/logUtils.d.ts +5 -0
  128. package/dist/esm/utils/logUtils.d.ts.map +1 -1
  129. package/dist/esm/utils/logUtils.js +7 -0
  130. package/dist/esm/utils/logUtils.js.map +1 -1
  131. package/dist/esm/utils/opentelemetryInstrumentationPatcher.d.ts.map +1 -1
  132. package/dist/esm/utils/opentelemetryInstrumentationPatcher.js +3 -2
  133. package/dist/esm/utils/opentelemetryInstrumentationPatcher.js.map +1 -1
  134. package/dist/esm/utils/statsbeat.d.ts.map +1 -1
  135. package/dist/esm/utils/statsbeat.js +36 -31
  136. package/dist/esm/utils/statsbeat.js.map +1 -1
  137. package/package.json +41 -30
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentialUtils.js","sourceRoot":"","sources":["../../../../src/metrics/quickpulse/credentialUtils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,yCAAyC,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAC;AAExD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kCAAkC;IAChD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IAC1E,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;QAChD,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,4BAA4B,IAAI,GAAG,CAAC,CAAC;YACvD,CAAC;YACD,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,KAAK,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC/C,OAAO,QAAQ;gBACb,CAAC,CAAC,IAAI,yBAAyB,CAAC,EAAE,QAAQ,EAAE,CAAC;gBAC7C,CAAC,CAAC,IAAI,yBAAyB,EAAE,CAAC;QACtC,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CACxB,8CAA8C,UAAU,uBAAuB,EAC/E,KAAK,CACN,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { ManagedIdentityCredential } from \"@azure/identity\";\nimport { APPLICATIONINSIGHTS_AUTHENTICATION_STRING } from \"../../types.js\";\nimport { Logger } from \"../../shared/logging/logger.js\";\n\n/**\n * Resolves an Azure Active Directory (AAD) credential from the\n * `APPLICATIONINSIGHTS_AUTHENTICATION_STRING` environment variable (the App Service /\n * Functions convention) which has the form `Authorization=AAD;ClientId=<client-id>`.\n * A `ManagedIdentityCredential` is created using the supplied `ClientId` when present.\n *\n * Returns `undefined` when the variable is absent, malformed, or does not request AAD\n * authorization. This is intended as a fallback for callers that were not given an\n * explicit credential.\n *\n * @returns A `ManagedIdentityCredential`, or `undefined` when none applies.\n * @internal\n */\nexport function getAuthenticationCredentialFromEnv(): ManagedIdentityCredential | undefined {\n const authString = process.env[APPLICATIONINSIGHTS_AUTHENTICATION_STRING];\n if (!authString) {\n return undefined;\n }\n try {\n const authStringMap = new Map<string, string>();\n for (const pair of authString.split(\";\")) {\n const keyValue = pair.split(\"=\");\n if (keyValue.length !== 2) {\n throw new Error(`Invalid key-value pair: \"${pair}\"`);\n }\n authStringMap.set(keyValue[0].toLowerCase(), keyValue[1]);\n }\n if (authStringMap.get(\"authorization\") === \"AAD\") {\n const clientId = authStringMap.get(\"clientid\");\n return clientId\n ? new ManagedIdentityCredential({ clientId })\n : new ManagedIdentityCredential();\n }\n } catch (error) {\n Logger.getInstance().error(\n `APPLICATIONINSIGHTS_AUTHENTICATION_STRING, ${authString}, has invalid format:`,\n error,\n );\n }\n return undefined;\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;AAKrC;;;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,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;CAa5D"}
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
- const locUrl = new url.URL(location);
101
- if (locUrl && locUrl.host) {
102
- this.endpointUrl = "https://" + locUrl.host;
103
- // Recreate the client so subsequent requests use the new endpoint
104
- this.quickpulseClient = this.createQuickpulseClient({
105
- endpoint: this.endpointUrl,
106
- credentials: { scopes: this.credentialScopes },
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;IAW5B,OAAO,CAAC,aAAa;CAoBtB"}
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
- let value;
125
- if (data.CustomDimensions.has(fieldName)) {
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":"AAAA,uCAAuC;AACvC,kCAAkC;AAclC,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AAErB,MAAM,OAAO,MAAM;IACV,qCAAqC,CAC1C,0BAAsD;QAEtD,0BAA0B,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;YACpD,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC9C,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAChE,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,kBAAkB,CAAC,iBAAoC,EAAE,IAAmB;QACjF,IAAI,iBAAiB,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChD,+FAA+F;YAC/F,sFAAsF;YACtF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,gGAAgG;QAChG,2FAA2F;QAC3F,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,iBAAiB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,sBAAsB,EAAE,EAAE;YAChE,OAAO,GAAG,OAAO,IAAI,IAAI,CAAC,2BAA2B,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;QACtF,CAAC,CAAC,CAAC;QACH,OAAO,OAAO,CAAC;IACjB,CAAC;IAEM,2BAA2B,CAChC,0BAAsD,EACtD,IAAmB;QAEnB,4EAA4E;QAC5E,KAAK,MAAM,MAAM,IAAI,0BAA0B,CAAC,OAAO,EAAE,CAAC;YACxD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;gBACpC,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,WAAW,CAAC,MAAkB,EAAE,IAAmB;QACzD,IAAI,MAAM,CAAC,SAAS,KAAK,GAAG,EAAE,CAAC;YAC7B,YAAY;YACZ,OAAO,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC5D,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,IAAI,SAA0D,CAAC;YAC/D,4DAA4D;YAC5D,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxB,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAA8B,CAAC,CAAC;YAC1D,CAAC;iBAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAiC,CAAC,CAAC;YAC7D,CAAC;iBAAM,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjC,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAgC,CAAC,CAAC;YAC5D,CAAC;iBAAM,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAA4B,CAAC,CAAC;YACxD,CAAC;iBAAM,CAAC;gBACN,OAAO,KAAK,CAAC,CAAC,wBAAwB;YACxC,CAAC;YAED,IAAI,MAAM,CAAC,SAAS,KAAK,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;gBAChE,IAAI,MAAM,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;oBACjC,OAAO,SAAS,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;gBACnE,CAAC;qBAAM,IAAI,MAAM,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;oBAC3C,OAAO,SAAS,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,CAAC;gBACnE,CAAC;YACH,CAAC;iBAAM,IACL,MAAM,CAAC,SAAS,KAAK,sBAAsB,CAAC,UAAU,CAAC,QAAQ,EAAE;gBACjE,MAAM,CAAC,SAAS,KAAK,mBAAmB,CAAC,YAAY,CAAC,QAAQ,EAAE;gBAChE,MAAM,CAAC,SAAS,KAAK,sBAAsB,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAC/D,CAAC;gBACD,MAAM,SAAS,GACb,MAAM,CAAC,SAAS,KAAK,sBAAsB,CAAC,QAAQ,CAAC,QAAQ,EAAE;oBAC7D,CAAC,CAAC,8BAA8B,CAAC,MAAM,CAAC,SAAS,CAAC;oBAClD,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBACnC,QAAQ,MAAM,CAAC,SAAS,EAAE,CAAC;oBACzB,KAAK,OAAO;wBACV,OAAO,SAAS,KAAK,SAAS,CAAC;oBACjC,KAAK,UAAU;wBACb,OAAO,SAAS,KAAK,SAAS,CAAC;oBACjC,KAAK,aAAa;wBAChB,OAAQ,SAAoB,GAAG,SAAS,CAAC;oBAC3C,KAAK,oBAAoB;wBACvB,OAAQ,SAAoB,IAAI,SAAS,CAAC;oBAC5C,KAAK,UAAU;wBACb,OAAQ,SAAoB,GAAG,SAAS,CAAC;oBAC3C,KAAK,iBAAiB;wBACpB,OAAQ,SAAoB,IAAI,SAAS,CAAC;oBAC5C;wBACE,OAAO,KAAK,CAAC;gBACjB,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,gBAAgB;gBAChB,OAAO,IAAI,CAAC,aAAa,CAAC,SAAmB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,mBAAmB,CAAC,MAAkB,EAAE,IAAmB;QACjE,MAAM,UAAU,GAAa,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,yFAAyF;QACzF,6EAA6E;QAC7E,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;YAClC,IAAI,QAAQ,KAAK,kBAAkB,EAAE,CAAC;gBACpC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC;oBACnD,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;wBAClE,OAAO,IAAI,CAAC;oBACd,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,gGAAgG;gBAChG,MAAM,KAAK,GAAW,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC7C,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;oBAClE,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,oBAAoB,CAAC,MAAkB,EAAE,IAAmB;QAClE,MAAM,SAAS,GAAW,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;QAC5E,IAAI,KAAyB,CAAC;QAC9B,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACzC,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAW,CAAC;QACzD,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC,CAAC,8DAA8D;QAC9E,CAAC;QACD,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IACvE,CAAC;IAEO,aAAa,CAAC,SAAiB,EAAE,SAAiB,EAAE,SAAiB;QAC3E,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,OAAO;gBACV,OAAO,SAAS,KAAK,SAAS,CAAC;YACjC,KAAK,UAAU;gBACb,OAAO,SAAS,KAAK,SAAS,CAAC;YACjC,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;gBAC/C,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;gBAC/C,OAAO,cAAc,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YACjD,CAAC;YACD,KAAK,gBAAgB,CAAC,CAAC,CAAC;gBACtB,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;gBAC/C,MAAM,cAAc,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;gBAC/C,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAClD,CAAC;YACD;gBACE,OAAO,KAAK,CAAC;QACjB,CAAC;IACH,CAAC;CACF","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":"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"}
1
+ {"version":3,"file":"liveMetrics.d.ts","sourceRoot":"","sources":["../../../../src/metrics/quickpulse/liveMetrics.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ import { QuickpulseMetricExporter } from "./export/exporter.js";
9
9
  import { QuickpulseSender } from "./export/sender.js";
10
10
  import { ConnectionStringParser } from "../../utils/connectionStringParser.js";
11
11
  import { DEFAULT_LIVEMETRICS_ENDPOINT } from "../../types.js";
12
+ import { getAuthenticationCredentialFromEnv } from "./credentialUtils.js";
12
13
  import { QuickPulseOpenTelemetryMetricNames } from "./types.js";
13
14
  import { hrTimeToMilliseconds, suppressTracing } from "@opentelemetry/core";
14
15
  import { getInstance } from "../../utils/statsbeat.js";
@@ -50,6 +51,8 @@ export class LiveMetrics {
50
51
  quickpulseExporter;
51
52
  pingSender;
52
53
  isCollectingData;
54
+ isDeactivating = false;
55
+ deactivatingPromise;
53
56
  lastSuccessTime = Date.now();
54
57
  handle;
55
58
  // Monitoring data point with common properties
@@ -114,17 +117,18 @@ export class LiveMetrics {
114
117
  };
115
118
  const parsedConnectionString = ConnectionStringParser.parse(this.config.azureMonitorExporterOptions.connectionString ||
116
119
  process.env["APPLICATIONINSIGHTS_CONNECTION_STRING"]);
120
+ const credential = this.config.azureMonitorExporterOptions.credential ?? getAuthenticationCredentialFromEnv();
117
121
  this.pingSender = new QuickpulseSender({
118
122
  endpointUrl: parsedConnectionString.liveendpoint || DEFAULT_LIVEMETRICS_ENDPOINT,
119
123
  instrumentationKey: parsedConnectionString.instrumentationkey || "",
120
- credential: this.config.azureMonitorExporterOptions.credential,
124
+ credential: credential,
121
125
  credentialScopes: parsedConnectionString.aadaudience ||
122
126
  this.config.azureMonitorExporterOptions.credentialScopes,
123
127
  });
124
128
  const exporterOptions = {
125
129
  endpointUrl: parsedConnectionString.liveendpoint || DEFAULT_LIVEMETRICS_ENDPOINT,
126
130
  instrumentationKey: parsedConnectionString.instrumentationkey || "",
127
- credential: this.config.azureMonitorExporterOptions.credential,
131
+ credential: credential,
128
132
  credentialScopes: parsedConnectionString.aadaudience ||
129
133
  this.config.azureMonitorExporterOptions.credentialScopes,
130
134
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
@@ -144,8 +148,15 @@ export class LiveMetrics {
144
148
  this.lastCpuUsage = process.cpuUsage();
145
149
  this.lastHrTime = process.hrtime.bigint();
146
150
  }
147
- shutdown() {
148
- this.meterProvider?.shutdown();
151
+ async shutdown() {
152
+ // Force collecting=false before tearing down so the shutdown's final
153
+ // force-flush export, if it fails, cannot trigger the deactivate/
154
+ // reactivate fallback in quickPulseDone(). Delegate to deactivateMetrics()
155
+ // which manages the in-flight deactivation promise so callers (including
156
+ // a concurrent failure-fallback in quickPulseDone) all observe the same
157
+ // completion and shutdown waits for any in-flight deactivation to finish.
158
+ this.isCollectingData = false;
159
+ await this.deactivateMetrics();
149
160
  }
150
161
  async goQuickpulse() {
151
162
  if (!this.isCollectingData) {
@@ -172,7 +183,6 @@ export class LiveMetrics {
172
183
  this.activateMetrics({ collectionInterval: this.postInterval });
173
184
  }
174
185
  }
175
- // eslint-disable-next-line @typescript-eslint/require-await
176
186
  async quickPulseDone(response) {
177
187
  if (!response) {
178
188
  if (!this.isCollectingData) {
@@ -182,9 +192,34 @@ export class LiveMetrics {
182
192
  }
183
193
  else {
184
194
  if (Date.now() - this.lastSuccessTime >= MAX_POST_WAIT_TIME) {
195
+ // Re-entrancy guard: MeterProvider.shutdown() triggers a final
196
+ // force-flush export which, on failure, re-invokes this callback
197
+ // synchronously from inside the shutdown's export call. If a
198
+ // deactivation is already in flight, bail out — awaiting the
199
+ // in-flight promise here would deadlock the exporter's callback.
200
+ if (this.isDeactivating) {
201
+ return;
202
+ }
185
203
  this.postInterval = FALLBACK_INTERVAL;
186
- this.deactivateMetrics();
187
- this.activateMetrics({ collectionInterval: this.postInterval });
204
+ try {
205
+ await this.deactivateMetrics();
206
+ }
207
+ catch (error) {
208
+ // The exporter invokes postCallback without awaiting it, so a
209
+ // rejection here would surface as an unhandled rejection. Swallow
210
+ // and log so the failure path stays contained.
211
+ Logger.getInstance().warn("Failed to deactivate Live Metrics during failure fallback", error);
212
+ }
213
+ // Reset the success-time baseline so the FALLBACK_INTERVAL backoff
214
+ // can take effect before we consider deactivating again.
215
+ this.lastSuccessTime = Date.now();
216
+ // Re-check after the await: shutdown() may have run concurrently and
217
+ // flipped isCollectingData to false. Don't restart collection in
218
+ // that case — doing so would re-create the meterProvider after
219
+ // shutdown has begun.
220
+ if (this.isCollectingData) {
221
+ this.activateMetrics({ collectionInterval: this.postInterval });
222
+ }
188
223
  }
189
224
  }
190
225
  }
@@ -200,7 +235,7 @@ export class LiveMetrics {
200
235
  // If collecting was stoped
201
236
  if (!this.isCollectingData && this.meterProvider) {
202
237
  this.etag = "";
203
- this.deactivateMetrics();
238
+ await this.deactivateMetrics();
204
239
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
205
240
  this.handle = setTimeout(this.goQuickpulse.bind(this), this.pingInterval);
206
241
  this.handle.unref();
@@ -294,16 +329,38 @@ export class LiveMetrics {
294
329
  /**
295
330
  * Deactivate metric collection
296
331
  */
297
- deactivateMetrics() {
298
- this.documents = [];
299
- this.validDocumentFilterConjuctionGroupInfos.clear();
300
- this.errorTracker.clearRunTimeErrors();
301
- this.errorTracker.clearValidationTimeErrors();
302
- this.validDerivedMetrics.clear();
303
- this.derivedMetricProjection.clearProjectionMaps();
304
- this.seenMetricIds.clear();
305
- this.meterProvider?.shutdown();
306
- this.meterProvider = undefined;
332
+ async deactivateMetrics() {
333
+ // Coalesce concurrent deactivations: callers (shutdown(), the
334
+ // failure-fallback in quickPulseDone(), and the "unsubscribed" branch in
335
+ // goQuickpulse()) can all race. Return the in-flight promise so every
336
+ // caller awaits the same completion and the underlying meterProvider
337
+ // shutdown only runs once.
338
+ if (this.deactivatingPromise) {
339
+ return this.deactivatingPromise;
340
+ }
341
+ this.isDeactivating = true;
342
+ this.deactivatingPromise = (async () => {
343
+ try {
344
+ this.documents = [];
345
+ this.validDocumentFilterConjuctionGroupInfos.clear();
346
+ this.errorTracker.clearRunTimeErrors();
347
+ this.errorTracker.clearValidationTimeErrors();
348
+ this.validDerivedMetrics.clear();
349
+ this.derivedMetricProjection.clearProjectionMaps();
350
+ this.seenMetricIds.clear();
351
+ // Capture and clear the reference before awaiting shutdown so any
352
+ // re-entrant calls triggered by the shutdown's final force-flush
353
+ // export observe meterProvider as undefined and exit early.
354
+ const provider = this.meterProvider;
355
+ this.meterProvider = undefined;
356
+ await provider?.shutdown();
357
+ }
358
+ finally {
359
+ this.isDeactivating = false;
360
+ this.deactivatingPromise = undefined;
361
+ }
362
+ })();
363
+ return this.deactivatingPromise;
307
364
  }
308
365
  /**
309
366
  * Force flush Meter Provider.