@azure/monitor-opentelemetry-exporter 1.0.0-beta.35 → 1.0.0-beta.37

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 (98) hide show
  1. package/dist/commonjs/Declarations/Constants.d.ts +10 -0
  2. package/dist/commonjs/Declarations/Constants.d.ts.map +1 -1
  3. package/dist/commonjs/Declarations/Constants.js +11 -1
  4. package/dist/commonjs/Declarations/Constants.js.map +1 -1
  5. package/dist/commonjs/Declarations/Contracts/Constants.d.ts +1 -1
  6. package/dist/commonjs/Declarations/Contracts/Constants.d.ts.map +1 -1
  7. package/dist/commonjs/Declarations/Contracts/Constants.js.map +1 -1
  8. package/dist/commonjs/export/metric.d.ts.map +1 -1
  9. package/dist/commonjs/export/metric.js +1 -1
  10. package/dist/commonjs/export/metric.js.map +1 -1
  11. package/dist/commonjs/export/statsbeat/customerSDKStats.d.ts +2 -2
  12. package/dist/commonjs/export/statsbeat/customerSDKStats.d.ts.map +1 -1
  13. package/dist/commonjs/export/statsbeat/customerSDKStats.js +11 -9
  14. package/dist/commonjs/export/statsbeat/customerSDKStats.js.map +1 -1
  15. package/dist/commonjs/export/statsbeat/statsbeatExporter.d.ts +5 -0
  16. package/dist/commonjs/export/statsbeat/statsbeatExporter.d.ts.map +1 -1
  17. package/dist/commonjs/export/statsbeat/statsbeatExporter.js +19 -5
  18. package/dist/commonjs/export/statsbeat/statsbeatExporter.js.map +1 -1
  19. package/dist/commonjs/export/statsbeat/statsbeatMetrics.d.ts.map +1 -1
  20. package/dist/commonjs/export/statsbeat/statsbeatMetrics.js +3 -2
  21. package/dist/commonjs/export/statsbeat/statsbeatMetrics.js.map +1 -1
  22. package/dist/commonjs/export/trace.d.ts +1 -0
  23. package/dist/commonjs/export/trace.d.ts.map +1 -1
  24. package/dist/commonjs/export/trace.js +9 -1
  25. package/dist/commonjs/export/trace.js.map +1 -1
  26. package/dist/commonjs/generated/applicationInsightsClient.js +1 -1
  27. package/dist/commonjs/generated/applicationInsightsClient.js.map +1 -1
  28. package/dist/commonjs/generated/models/index.d.ts.map +1 -1
  29. package/dist/commonjs/generated/models/index.js.map +1 -1
  30. package/dist/commonjs/generated/models/mappers.js +11 -11
  31. package/dist/commonjs/generated/models/mappers.js.map +1 -1
  32. package/dist/commonjs/platform/nodejs/baseSender.d.ts +1 -0
  33. package/dist/commonjs/platform/nodejs/baseSender.d.ts.map +1 -1
  34. package/dist/commonjs/platform/nodejs/baseSender.js +35 -16
  35. package/dist/commonjs/platform/nodejs/baseSender.js.map +1 -1
  36. package/dist/commonjs/platform/nodejs/persist/fileSystemPersist.d.ts +15 -0
  37. package/dist/commonjs/platform/nodejs/persist/fileSystemPersist.d.ts.map +1 -1
  38. package/dist/commonjs/platform/nodejs/persist/fileSystemPersist.js +65 -2
  39. package/dist/commonjs/platform/nodejs/persist/fileSystemPersist.js.map +1 -1
  40. package/dist/commonjs/tsdoc-metadata.json +1 -1
  41. package/dist/commonjs/utils/common.d.ts +2 -2
  42. package/dist/commonjs/utils/common.d.ts.map +1 -1
  43. package/dist/commonjs/utils/common.js +16 -11
  44. package/dist/commonjs/utils/common.js.map +1 -1
  45. package/dist/commonjs/utils/constants/applicationinsights.d.ts +1 -1
  46. package/dist/commonjs/utils/constants/applicationinsights.js +1 -1
  47. package/dist/commonjs/utils/constants/applicationinsights.js.map +1 -1
  48. package/dist/commonjs/utils/logUtils.js +2 -2
  49. package/dist/commonjs/utils/logUtils.js.map +1 -1
  50. package/dist/esm/Declarations/Constants.d.ts +10 -0
  51. package/dist/esm/Declarations/Constants.d.ts.map +1 -1
  52. package/dist/esm/Declarations/Constants.js +10 -0
  53. package/dist/esm/Declarations/Constants.js.map +1 -1
  54. package/dist/esm/Declarations/Contracts/Constants.d.ts +1 -1
  55. package/dist/esm/Declarations/Contracts/Constants.d.ts.map +1 -1
  56. package/dist/esm/Declarations/Contracts/Constants.js.map +1 -1
  57. package/dist/esm/export/metric.d.ts.map +1 -1
  58. package/dist/esm/export/metric.js +1 -1
  59. package/dist/esm/export/metric.js.map +1 -1
  60. package/dist/esm/export/statsbeat/customerSDKStats.d.ts +2 -2
  61. package/dist/esm/export/statsbeat/customerSDKStats.d.ts.map +1 -1
  62. package/dist/esm/export/statsbeat/customerSDKStats.js +11 -9
  63. package/dist/esm/export/statsbeat/customerSDKStats.js.map +1 -1
  64. package/dist/esm/export/statsbeat/statsbeatExporter.d.ts +5 -0
  65. package/dist/esm/export/statsbeat/statsbeatExporter.d.ts.map +1 -1
  66. package/dist/esm/export/statsbeat/statsbeatExporter.js +19 -5
  67. package/dist/esm/export/statsbeat/statsbeatExporter.js.map +1 -1
  68. package/dist/esm/export/statsbeat/statsbeatMetrics.d.ts.map +1 -1
  69. package/dist/esm/export/statsbeat/statsbeatMetrics.js +3 -2
  70. package/dist/esm/export/statsbeat/statsbeatMetrics.js.map +1 -1
  71. package/dist/esm/export/trace.d.ts +1 -0
  72. package/dist/esm/export/trace.d.ts.map +1 -1
  73. package/dist/esm/export/trace.js +9 -1
  74. package/dist/esm/export/trace.js.map +1 -1
  75. package/dist/esm/generated/applicationInsightsClient.js +1 -1
  76. package/dist/esm/generated/applicationInsightsClient.js.map +1 -1
  77. package/dist/esm/generated/models/index.d.ts.map +1 -1
  78. package/dist/esm/generated/models/index.js.map +1 -1
  79. package/dist/esm/generated/models/mappers.js +11 -11
  80. package/dist/esm/generated/models/mappers.js.map +1 -1
  81. package/dist/esm/platform/nodejs/baseSender.d.ts +1 -0
  82. package/dist/esm/platform/nodejs/baseSender.d.ts.map +1 -1
  83. package/dist/esm/platform/nodejs/baseSender.js +36 -17
  84. package/dist/esm/platform/nodejs/baseSender.js.map +1 -1
  85. package/dist/esm/platform/nodejs/persist/fileSystemPersist.d.ts +15 -0
  86. package/dist/esm/platform/nodejs/persist/fileSystemPersist.d.ts.map +1 -1
  87. package/dist/esm/platform/nodejs/persist/fileSystemPersist.js +66 -4
  88. package/dist/esm/platform/nodejs/persist/fileSystemPersist.js.map +1 -1
  89. package/dist/esm/utils/common.d.ts +2 -2
  90. package/dist/esm/utils/common.d.ts.map +1 -1
  91. package/dist/esm/utils/common.js +17 -12
  92. package/dist/esm/utils/common.js.map +1 -1
  93. package/dist/esm/utils/constants/applicationinsights.d.ts +1 -1
  94. package/dist/esm/utils/constants/applicationinsights.js +1 -1
  95. package/dist/esm/utils/constants/applicationinsights.js.map +1 -1
  96. package/dist/esm/utils/logUtils.js +2 -2
  97. package/dist/esm/utils/logUtils.js.map +1 -1
  98. package/package.json +18 -14
@@ -12,7 +12,6 @@ const longIntervalStatsbeatMetrics_js_1 = require("../../export/statsbeat/longIn
12
12
  const types_js_2 = require("../../export/statsbeat/types.js");
13
13
  const breezeUtils_js_1 = require("../../utils/breezeUtils.js");
14
14
  const Constants_js_1 = require("../../Declarations/Constants.js");
15
- const customerSDKStats_js_1 = require("../../export/statsbeat/customerSDKStats.js");
16
15
  const DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60_000;
17
16
  /**
18
17
  * Base sender class
@@ -55,12 +54,24 @@ class BaseSender {
55
54
  api_1.diag.warn(`Invalid value for APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL environment variable: '${envValue}'. Expected a positive number (seconds). Using default export interval.`);
56
55
  }
57
56
  }
58
- this.customerSDKStatsMetrics = customerSDKStats_js_1.CustomerSDKStatsMetrics.getInstance({
59
- instrumentationKey: options.instrumentationKey,
60
- endpointUrl: options.endpointUrl,
61
- disableOfflineStorage: this.disableOfflineStorage,
62
- networkCollectionInterval: exportInterval,
63
- });
57
+ // Initialize customer SDK stats metrics asynchronously to avoid circular dependency
58
+ // Only initialize if not already set (e.g., by tests)
59
+ if (!this.customerSDKStatsMetrics) {
60
+ import("../../export/statsbeat/customerSDKStats.js")
61
+ .then((module) => module.CustomerSDKStatsMetrics.getInstance({
62
+ instrumentationKey: options.instrumentationKey,
63
+ endpointUrl: options.endpointUrl,
64
+ disableOfflineStorage: this.disableOfflineStorage,
65
+ networkCollectionInterval: exportInterval,
66
+ }))
67
+ .then((metrics) => {
68
+ this.customerSDKStatsMetrics = metrics;
69
+ return;
70
+ })
71
+ .catch((error) => {
72
+ api_1.diag.warn("Failed to initialize customer SDK stats metrics:", error);
73
+ });
74
+ }
64
75
  }
65
76
  }
66
77
  this.persister = new index_js_1.FileSystemPersist(options.instrumentationKey, options.exporterOptions, this.customerSDKStatsMetrics);
@@ -152,9 +163,9 @@ class BaseSender {
152
163
  const filteredSuccessfulEnvelopes = successfulEnvelopes.filter(Boolean);
153
164
  this.customerSDKStatsMetrics?.countDroppedItems(filteredSuccessfulEnvelopes, statusCode);
154
165
  }
155
- return {
166
+ return this.buildExportResult({
156
167
  code: core_1.ExportResultCode.FAILED,
157
- };
168
+ });
158
169
  }
159
170
  else {
160
171
  // calls resultCallback(ExportResult) based on result of persister.push
@@ -178,9 +189,9 @@ class BaseSender {
178
189
  this.incrementStatsbeatFailure();
179
190
  this.customerSDKStatsMetrics?.countDroppedItems(envelopes, types_js_2.DropCode.CLIENT_EXCEPTION);
180
191
  }
181
- return {
192
+ return this.buildExportResult({
182
193
  code: core_1.ExportResultCode.FAILED,
183
- };
194
+ });
184
195
  }
185
196
  }
186
197
  catch (error) {
@@ -208,7 +219,7 @@ class BaseSender {
208
219
  this.networkStatsbeatMetrics?.countException(redirectError);
209
220
  this.customerSDKStatsMetrics?.countDroppedItems(envelopes, types_js_2.DropCode.CLIENT_EXCEPTION, redirectError.message, types_js_1.ExceptionType.CLIENT_EXCEPTION);
210
221
  }
211
- return { code: core_1.ExportResultCode.FAILED, error: redirectError };
222
+ return this.buildExportResult({ code: core_1.ExportResultCode.FAILED, error: redirectError });
212
223
  }
213
224
  }
214
225
  else if (restError.statusCode &&
@@ -250,7 +261,7 @@ class BaseSender {
250
261
  this.customerSDKStatsMetrics?.countDroppedItems(envelopes, types_js_2.DropCode.CLIENT_EXCEPTION, restError.message);
251
262
  api_1.diag.error("Envelopes could not be exported and are not retriable. Error message:", restError.message);
252
263
  }
253
- return { code: core_1.ExportResultCode.FAILED, error: restError };
264
+ return this.buildExportResult({ code: core_1.ExportResultCode.FAILED, error: restError });
254
265
  }
255
266
  }
256
267
  /**
@@ -261,10 +272,10 @@ class BaseSender {
261
272
  const success = await this.persister.push(envelopes);
262
273
  return success
263
274
  ? { code: core_1.ExportResultCode.SUCCESS }
264
- : {
275
+ : this.buildExportResult({
265
276
  code: core_1.ExportResultCode.FAILED,
266
277
  error: new Error("Failed to persist envelope in disk."),
267
- };
278
+ });
268
279
  }
269
280
  catch (ex) {
270
281
  if (!this.isStatsbeatSender) {
@@ -273,7 +284,7 @@ class BaseSender {
273
284
  this.customerSDKStatsMetrics?.countDroppedItems(envelopes, types_js_2.DropCode.CLIENT_STORAGE_DISABLED);
274
285
  }
275
286
  }
276
- return { code: core_1.ExportResultCode.FAILED, error: ex };
287
+ return this.buildExportResult({ code: core_1.ExportResultCode.FAILED, error: ex });
277
288
  }
278
289
  }
279
290
  /**
@@ -321,6 +332,14 @@ class BaseSender {
321
332
  }
322
333
  return false;
323
334
  }
335
+ // Silence noisy failures from statsbeat OTel metric readers unless logging is explicitly enabled
336
+ buildExportResult(result) {
337
+ const shouldSurfaceStatsbeatFailures = !!process.env[Constants_js_1.ENV_APPLICATIONINSIGHTS_SDK_STATS_LOGGING];
338
+ if (this.isStatsbeatSender && result.code === core_1.ExportResultCode.FAILED) {
339
+ return shouldSurfaceStatsbeatFailures ? result : { code: core_1.ExportResultCode.SUCCESS };
340
+ }
341
+ return result;
342
+ }
324
343
  }
325
344
  exports.BaseSender = BaseSender;
326
345
  //# sourceMappingURL=baseSender.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"baseSender.js","sourceRoot":"","sources":["../../../../src/platform/nodejs/baseSender.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { diag } from \"@opentelemetry/api\";\nimport type { PersistentStorage, SenderResult } from \"../../types.js\";\nimport { ExceptionType } from \"../../export/statsbeat/types.js\";\nimport type { AzureMonitorExporterOptions } from \"../../config.js\";\nimport { FileSystemPersist } from \"./persist/index.js\";\nimport type { ExportResult } from \"@opentelemetry/core\";\nimport { ExportResultCode } from \"@opentelemetry/core\";\nimport { NetworkStatsbeatMetrics } from \"../../export/statsbeat/networkStatsbeatMetrics.js\";\nimport { LongIntervalStatsbeatMetrics } from \"../../export/statsbeat/longIntervalStatsbeatMetrics.js\";\nimport type { RestError } from \"@azure/core-rest-pipeline\";\nimport {\n DropCode,\n RetryCode,\n MAX_STATSBEAT_FAILURES,\n isStatsbeatShutdownStatus,\n} from \"../../export/statsbeat/types.js\";\nimport type { BreezeResponse } from \"../../utils/breezeUtils.js\";\nimport { isRetriable } from \"../../utils/breezeUtils.js\";\nimport type { TelemetryItem as Envelope } from \"../../generated/index.js\";\nimport {\n ENV_APPLICATIONINSIGHTS_SDKSTATS_ENABLED_PREVIEW,\n ENV_APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL,\n RetriableRestErrorTypes,\n} from \"../../Declarations/Constants.js\";\nimport { CustomerSDKStatsMetrics } from \"../../export/statsbeat/customerSDKStats.js\";\n\nconst DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60_000;\n\n/**\n * Base sender class\n * @internal\n */\nexport abstract class BaseSender {\n private readonly persister: PersistentStorage;\n private numConsecutiveRedirects: number;\n private retryTimer: NodeJS.Timeout | null;\n private networkStatsbeatMetrics: NetworkStatsbeatMetrics | undefined;\n private customerSDKStatsMetrics: CustomerSDKStatsMetrics | undefined;\n private longIntervalStatsbeatMetrics;\n private statsbeatFailureCount: number = 0;\n private batchSendRetryIntervalMs: number = DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS;\n private isStatsbeatSender: boolean;\n private disableOfflineStorage: boolean;\n\n constructor(options: {\n endpointUrl: string;\n instrumentationKey: string;\n trackStatsbeat: boolean;\n exporterOptions: AzureMonitorExporterOptions;\n aadAudience?: string;\n isStatsbeatSender?: boolean;\n }) {\n this.numConsecutiveRedirects = 0;\n this.disableOfflineStorage = options.exporterOptions.disableOfflineStorage || false;\n if (options.trackStatsbeat) {\n this.networkStatsbeatMetrics = NetworkStatsbeatMetrics.getInstance({\n instrumentationKey: options.instrumentationKey,\n endpointUrl: options.endpointUrl,\n disableOfflineStorage: this.disableOfflineStorage,\n });\n this.longIntervalStatsbeatMetrics = LongIntervalStatsbeatMetrics.getInstance({\n instrumentationKey: options.instrumentationKey,\n endpointUrl: options.endpointUrl,\n disableOfflineStorage: this.disableOfflineStorage,\n });\n if (process.env[ENV_APPLICATIONINSIGHTS_SDKSTATS_ENABLED_PREVIEW]) {\n let exportInterval: number | undefined;\n if (process.env[ENV_APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL]) {\n const envValue = process.env[ENV_APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL];\n const exportIntervalSeconds = parseInt(envValue, 10);\n if (!isNaN(exportIntervalSeconds) && exportIntervalSeconds > 0) {\n exportInterval = exportIntervalSeconds * 1000; // Convert seconds to milliseconds\n } else {\n diag.warn(\n `Invalid value for APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL environment variable: '${envValue}'. Expected a positive number (seconds). Using default export interval.`,\n );\n }\n }\n this.customerSDKStatsMetrics = CustomerSDKStatsMetrics.getInstance({\n instrumentationKey: options.instrumentationKey,\n endpointUrl: options.endpointUrl,\n disableOfflineStorage: this.disableOfflineStorage,\n networkCollectionInterval: exportInterval,\n });\n }\n }\n this.persister = new FileSystemPersist(\n options.instrumentationKey,\n options.exporterOptions,\n this.customerSDKStatsMetrics,\n );\n this.retryTimer = null;\n this.isStatsbeatSender = options.isStatsbeatSender || false;\n }\n\n abstract send(payload: unknown[]): Promise<SenderResult>;\n abstract shutdown(): Promise<void>;\n abstract handlePermanentRedirect(location: string | undefined): void;\n\n /**\n * Export envelopes\n */\n public async exportEnvelopes(envelopes: Envelope[]): Promise<ExportResult> {\n diag.info(`Exporting ${envelopes.length} envelope(s)`);\n\n if (envelopes.length < 1) {\n return { code: ExportResultCode.SUCCESS };\n }\n\n try {\n const startTime = new Date().getTime();\n const { result, statusCode } = await this.send(envelopes);\n const endTime = new Date().getTime();\n const duration = endTime - startTime;\n this.numConsecutiveRedirects = 0;\n\n if (statusCode === 200) {\n // Success -- @todo: start retry timer\n if (!this.retryTimer) {\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.sendFirstPersistedFile();\n }, this.batchSendRetryIntervalMs);\n this.retryTimer.unref();\n }\n // If we are not exporting statsbeat and statsbeat is not disabled -- count success\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countSuccess(duration);\n this.customerSDKStatsMetrics?.countSuccessfulItems(envelopes);\n }\n return { code: ExportResultCode.SUCCESS };\n } else if (statusCode && isRetriable(statusCode)) {\n // Failed -- persist failed data\n if (statusCode === 429 || statusCode === 439) {\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countThrottle(statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, statusCode);\n }\n return {\n code: ExportResultCode.SUCCESS,\n };\n }\n if (result) {\n diag.info(result);\n const breezeResponse = JSON.parse(result) as BreezeResponse;\n const filteredEnvelopes: Envelope[] = [];\n // Create a list of successful envelopes by filtering out the failed ones for customer SDK Stats\n const successfulEnvelopes: Envelope[] = [...envelopes];\n\n // If we have a partial success, count the succeeded envelopes\n if (breezeResponse.itemsAccepted > 0 && statusCode === 206 && !this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countSuccess(duration);\n }\n // Figure out if we need to either retry or count failures\n if (breezeResponse.errors) {\n breezeResponse.errors.forEach((error) => {\n // Mark as undefined so we don't process them in countSuccessfulEnvelopes\n successfulEnvelopes[error.index] = undefined as unknown as Envelope;\n\n // Add to retry list if status code is retriable\n if (error.statusCode && isRetriable(error.statusCode)) {\n filteredEnvelopes.push(envelopes[error.index]);\n }\n });\n }\n\n // If we have a partial success, count the succeeded envelopes\n if (breezeResponse.itemsAccepted > 0) {\n // Count only the successful envelopes (non-undefined)\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countSuccess(duration);\n this.customerSDKStatsMetrics?.countSuccessfulItems(envelopes);\n }\n }\n if (filteredEnvelopes.length > 0) {\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countRetry(statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, statusCode);\n }\n // calls resultCallback(ExportResult) based on result of persister.push\n return await this.persist(filteredEnvelopes);\n }\n // Failed -- not retriable\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countFailure(duration, statusCode);\n // Count dropped items for customer SDK Stats for non-retriable status codes\n const filteredSuccessfulEnvelopes = successfulEnvelopes.filter(Boolean);\n this.customerSDKStatsMetrics?.countDroppedItems(\n filteredSuccessfulEnvelopes,\n statusCode,\n );\n }\n return {\n code: ExportResultCode.FAILED,\n };\n } else {\n // calls resultCallback(ExportResult) based on result of persister.push\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countRetry(statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, statusCode);\n }\n return await this.persist(envelopes);\n }\n } else {\n // Failed -- not retriable\n if (this.networkStatsbeatMetrics && !this.isStatsbeatSender) {\n if (statusCode) {\n this.networkStatsbeatMetrics.countFailure(duration, statusCode);\n this.customerSDKStatsMetrics?.countDroppedItems(envelopes, statusCode);\n }\n } else {\n // Handles all other status codes or client exceptions for Statsbeat\n this.incrementStatsbeatFailure();\n this.customerSDKStatsMetrics?.countDroppedItems(envelopes, DropCode.CLIENT_EXCEPTION);\n }\n return {\n code: ExportResultCode.FAILED,\n };\n }\n } catch (error: any) {\n const restError = error as RestError;\n if (\n restError.statusCode &&\n (restError.statusCode === 307 || // Temporary redirect\n restError.statusCode === 308)\n ) {\n // Permanent redirect\n this.numConsecutiveRedirects++;\n // To prevent circular redirects\n if (this.numConsecutiveRedirects < 10) {\n if (restError.response && restError.response.headers) {\n const location = restError.response.headers.get(\"location\");\n if (location) {\n // Update sender URL\n this.handlePermanentRedirect(location);\n // Send to redirect endpoint as HTTPs library doesn't handle redirect automatically\n return this.exportEnvelopes(envelopes);\n }\n }\n } else {\n const redirectError = new Error(\"Circular redirect\");\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countException(redirectError);\n this.customerSDKStatsMetrics?.countDroppedItems(\n envelopes,\n DropCode.CLIENT_EXCEPTION,\n redirectError.message,\n ExceptionType.CLIENT_EXCEPTION,\n );\n }\n return { code: ExportResultCode.FAILED, error: redirectError };\n }\n } else if (\n restError.statusCode &&\n isRetriable(restError.statusCode) &&\n !this.isStatsbeatSender\n ) {\n this.networkStatsbeatMetrics?.countRetry(restError.statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, restError.statusCode);\n return this.persist(envelopes);\n } else if (\n restError.statusCode === 400 &&\n restError.message.includes(\"Invalid instrumentation key\")\n ) {\n // Invalid instrumentation key, shutdown statsbeat, fail silently\n this.shutdownStatsbeat();\n return { code: ExportResultCode.SUCCESS };\n } else if (\n restError.statusCode &&\n this.isStatsbeatSender &&\n isStatsbeatShutdownStatus(restError.statusCode)\n ) {\n // If the status code is a shutdown status code for statsbeat, shutdown statsbeat and fail silently\n this.incrementStatsbeatFailure();\n return { code: ExportResultCode.SUCCESS };\n }\n\n // For retriable REST errors\n if (this.isRetriableRestError(restError) && !this.isStatsbeatSender) {\n if (this.customerSDKStatsMetrics?.isTimeoutError(restError) && !this.isStatsbeatSender) {\n this.customerSDKStatsMetrics?.countRetryItems(\n envelopes,\n RetryCode.CLIENT_TIMEOUT,\n \"timeout_exception\",\n ExceptionType.TIMEOUT_EXCEPTION,\n );\n diag.error(\"Request timed out. Error message:\", restError.message);\n } else if (restError.statusCode) {\n this.networkStatsbeatMetrics?.countRetry(restError.statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, restError.statusCode);\n }\n diag.error(\n \"Retrying due to transient client side error. Error message:\",\n restError.message,\n );\n return this.persist(envelopes);\n }\n // For non-retriable REST errors or client exceptions\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countException(restError);\n this.customerSDKStatsMetrics?.countDroppedItems(\n envelopes,\n DropCode.CLIENT_EXCEPTION,\n restError.message,\n );\n diag.error(\n \"Envelopes could not be exported and are not retriable. Error message:\",\n restError.message,\n );\n }\n return { code: ExportResultCode.FAILED, error: restError };\n }\n }\n\n /**\n * Persist envelopes to disk\n */\n private async persist(envelopes: unknown[]): Promise<ExportResult> {\n try {\n const success = await this.persister.push(envelopes);\n return success\n ? { code: ExportResultCode.SUCCESS }\n : {\n code: ExportResultCode.FAILED,\n error: new Error(\"Failed to persist envelope in disk.\"),\n };\n } catch (ex: any) {\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countWriteFailure();\n if (this.disableOfflineStorage && envelopes) {\n this.customerSDKStatsMetrics?.countDroppedItems(\n envelopes as Envelope[],\n DropCode.CLIENT_STORAGE_DISABLED,\n );\n }\n }\n return { code: ExportResultCode.FAILED, error: ex };\n }\n }\n\n /**\n * Disable collection of statsbeat metrics after max failures\n */\n private incrementStatsbeatFailure(): void {\n this.statsbeatFailureCount++;\n if (this.statsbeatFailureCount > MAX_STATSBEAT_FAILURES) {\n this.shutdownStatsbeat();\n }\n }\n\n /**\n * Shutdown statsbeat metrics\n */\n private shutdownStatsbeat(): void {\n if (this.networkStatsbeatMetrics) {\n this.networkStatsbeatMetrics.shutdown();\n }\n if (this.longIntervalStatsbeatMetrics) {\n this.longIntervalStatsbeatMetrics?.shutdown();\n }\n if (this.customerSDKStatsMetrics) {\n this.customerSDKStatsMetrics.shutdown();\n }\n this.statsbeatFailureCount = 0;\n }\n\n private async sendFirstPersistedFile(): Promise<void> {\n const envelopes = (await this.persister.shift()) as Envelope[] | null;\n try {\n if (envelopes) {\n await this.send(envelopes);\n }\n } catch (err: any) {\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countReadFailure();\n }\n diag.warn(`Failed to fetch persisted file`, err);\n }\n }\n\n private isRetriableRestError(error: RestError): boolean {\n const restErrorTypes: string[] = Object.values(RetriableRestErrorTypes);\n if (error && error.code && restErrorTypes.includes(error.code)) {\n return true;\n }\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"baseSender.js","sourceRoot":"","sources":["../../../../src/platform/nodejs/baseSender.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { diag } from \"@opentelemetry/api\";\nimport type { PersistentStorage, SenderResult } from \"../../types.js\";\nimport { ExceptionType } from \"../../export/statsbeat/types.js\";\nimport type { AzureMonitorExporterOptions } from \"../../config.js\";\nimport { FileSystemPersist } from \"./persist/index.js\";\nimport type { ExportResult } from \"@opentelemetry/core\";\nimport { ExportResultCode } from \"@opentelemetry/core\";\nimport { NetworkStatsbeatMetrics } from \"../../export/statsbeat/networkStatsbeatMetrics.js\";\nimport { LongIntervalStatsbeatMetrics } from \"../../export/statsbeat/longIntervalStatsbeatMetrics.js\";\nimport type { RestError } from \"@azure/core-rest-pipeline\";\nimport {\n DropCode,\n RetryCode,\n MAX_STATSBEAT_FAILURES,\n isStatsbeatShutdownStatus,\n} from \"../../export/statsbeat/types.js\";\nimport type { BreezeResponse } from \"../../utils/breezeUtils.js\";\nimport { isRetriable } from \"../../utils/breezeUtils.js\";\nimport type { TelemetryItem as Envelope } from \"../../generated/index.js\";\nimport {\n ENV_APPLICATIONINSIGHTS_SDKSTATS_ENABLED_PREVIEW,\n ENV_APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL,\n ENV_APPLICATIONINSIGHTS_SDK_STATS_LOGGING,\n RetriableRestErrorTypes,\n} from \"../../Declarations/Constants.js\";\nimport { CustomerSDKStatsMetrics } from \"../../export/statsbeat/customerSDKStats.js\";\n\nconst DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS = 60_000;\n\n/**\n * Base sender class\n * @internal\n */\nexport abstract class BaseSender {\n private readonly persister: PersistentStorage;\n private numConsecutiveRedirects: number;\n private retryTimer: NodeJS.Timeout | null;\n private networkStatsbeatMetrics: NetworkStatsbeatMetrics | undefined;\n private customerSDKStatsMetrics: CustomerSDKStatsMetrics | undefined;\n private longIntervalStatsbeatMetrics;\n private statsbeatFailureCount: number = 0;\n private batchSendRetryIntervalMs: number = DEFAULT_BATCH_SEND_RETRY_INTERVAL_MS;\n private isStatsbeatSender: boolean;\n private disableOfflineStorage: boolean;\n\n constructor(options: {\n endpointUrl: string;\n instrumentationKey: string;\n trackStatsbeat: boolean;\n exporterOptions: AzureMonitorExporterOptions;\n aadAudience?: string;\n isStatsbeatSender?: boolean;\n }) {\n this.numConsecutiveRedirects = 0;\n this.disableOfflineStorage = options.exporterOptions.disableOfflineStorage || false;\n if (options.trackStatsbeat) {\n this.networkStatsbeatMetrics = NetworkStatsbeatMetrics.getInstance({\n instrumentationKey: options.instrumentationKey,\n endpointUrl: options.endpointUrl,\n disableOfflineStorage: this.disableOfflineStorage,\n });\n this.longIntervalStatsbeatMetrics = LongIntervalStatsbeatMetrics.getInstance({\n instrumentationKey: options.instrumentationKey,\n endpointUrl: options.endpointUrl,\n disableOfflineStorage: this.disableOfflineStorage,\n });\n if (process.env[ENV_APPLICATIONINSIGHTS_SDKSTATS_ENABLED_PREVIEW]) {\n let exportInterval: number | undefined;\n if (process.env[ENV_APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL]) {\n const envValue = process.env[ENV_APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL];\n const exportIntervalSeconds = parseInt(envValue, 10);\n if (!isNaN(exportIntervalSeconds) && exportIntervalSeconds > 0) {\n exportInterval = exportIntervalSeconds * 1000; // Convert seconds to milliseconds\n } else {\n diag.warn(\n `Invalid value for APPLICATIONINSIGHTS_SDKSTATS_EXPORT_INTERVAL environment variable: '${envValue}'. Expected a positive number (seconds). Using default export interval.`,\n );\n }\n }\n // Initialize customer SDK stats metrics asynchronously to avoid circular dependency\n // Only initialize if not already set (e.g., by tests)\n if (!this.customerSDKStatsMetrics) {\n import(\"../../export/statsbeat/customerSDKStats.js\")\n .then((module) =>\n module.CustomerSDKStatsMetrics.getInstance({\n instrumentationKey: options.instrumentationKey,\n endpointUrl: options.endpointUrl,\n disableOfflineStorage: this.disableOfflineStorage,\n networkCollectionInterval: exportInterval,\n }),\n )\n .then((metrics) => {\n this.customerSDKStatsMetrics = metrics;\n return;\n })\n .catch((error) => {\n diag.warn(\"Failed to initialize customer SDK stats metrics:\", error);\n });\n }\n }\n }\n this.persister = new FileSystemPersist(\n options.instrumentationKey,\n options.exporterOptions,\n this.customerSDKStatsMetrics,\n );\n this.retryTimer = null;\n this.isStatsbeatSender = options.isStatsbeatSender || false;\n }\n\n abstract send(payload: unknown[]): Promise<SenderResult>;\n abstract shutdown(): Promise<void>;\n abstract handlePermanentRedirect(location: string | undefined): void;\n\n /**\n * Export envelopes\n */\n public async exportEnvelopes(envelopes: Envelope[]): Promise<ExportResult> {\n diag.info(`Exporting ${envelopes.length} envelope(s)`);\n\n if (envelopes.length < 1) {\n return { code: ExportResultCode.SUCCESS };\n }\n\n try {\n const startTime = new Date().getTime();\n const { result, statusCode } = await this.send(envelopes);\n const endTime = new Date().getTime();\n const duration = endTime - startTime;\n this.numConsecutiveRedirects = 0;\n\n if (statusCode === 200) {\n // Success -- @todo: start retry timer\n if (!this.retryTimer) {\n this.retryTimer = setTimeout(() => {\n this.retryTimer = null;\n this.sendFirstPersistedFile();\n }, this.batchSendRetryIntervalMs);\n this.retryTimer.unref();\n }\n // If we are not exporting statsbeat and statsbeat is not disabled -- count success\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countSuccess(duration);\n this.customerSDKStatsMetrics?.countSuccessfulItems(envelopes);\n }\n return { code: ExportResultCode.SUCCESS };\n } else if (statusCode && isRetriable(statusCode)) {\n // Failed -- persist failed data\n if (statusCode === 429 || statusCode === 439) {\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countThrottle(statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, statusCode);\n }\n return {\n code: ExportResultCode.SUCCESS,\n };\n }\n if (result) {\n diag.info(result);\n const breezeResponse = JSON.parse(result) as BreezeResponse;\n const filteredEnvelopes: Envelope[] = [];\n // Create a list of successful envelopes by filtering out the failed ones for customer SDK Stats\n const successfulEnvelopes: Envelope[] = [...envelopes];\n\n // If we have a partial success, count the succeeded envelopes\n if (breezeResponse.itemsAccepted > 0 && statusCode === 206 && !this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countSuccess(duration);\n }\n // Figure out if we need to either retry or count failures\n if (breezeResponse.errors) {\n breezeResponse.errors.forEach((error) => {\n // Mark as undefined so we don't process them in countSuccessfulEnvelopes\n successfulEnvelopes[error.index] = undefined as unknown as Envelope;\n\n // Add to retry list if status code is retriable\n if (error.statusCode && isRetriable(error.statusCode)) {\n filteredEnvelopes.push(envelopes[error.index]);\n }\n });\n }\n\n // If we have a partial success, count the succeeded envelopes\n if (breezeResponse.itemsAccepted > 0) {\n // Count only the successful envelopes (non-undefined)\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countSuccess(duration);\n this.customerSDKStatsMetrics?.countSuccessfulItems(envelopes);\n }\n }\n if (filteredEnvelopes.length > 0) {\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countRetry(statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, statusCode);\n }\n // calls resultCallback(ExportResult) based on result of persister.push\n return await this.persist(filteredEnvelopes);\n }\n // Failed -- not retriable\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countFailure(duration, statusCode);\n // Count dropped items for customer SDK Stats for non-retriable status codes\n const filteredSuccessfulEnvelopes = successfulEnvelopes.filter(Boolean);\n this.customerSDKStatsMetrics?.countDroppedItems(\n filteredSuccessfulEnvelopes,\n statusCode,\n );\n }\n return this.buildExportResult({\n code: ExportResultCode.FAILED,\n });\n } else {\n // calls resultCallback(ExportResult) based on result of persister.push\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countRetry(statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, statusCode);\n }\n return await this.persist(envelopes);\n }\n } else {\n // Failed -- not retriable\n if (this.networkStatsbeatMetrics && !this.isStatsbeatSender) {\n if (statusCode) {\n this.networkStatsbeatMetrics.countFailure(duration, statusCode);\n this.customerSDKStatsMetrics?.countDroppedItems(envelopes, statusCode);\n }\n } else {\n // Handles all other status codes or client exceptions for Statsbeat\n this.incrementStatsbeatFailure();\n this.customerSDKStatsMetrics?.countDroppedItems(envelopes, DropCode.CLIENT_EXCEPTION);\n }\n return this.buildExportResult({\n code: ExportResultCode.FAILED,\n });\n }\n } catch (error: any) {\n const restError = error as RestError;\n if (\n restError.statusCode &&\n (restError.statusCode === 307 || // Temporary redirect\n restError.statusCode === 308)\n ) {\n // Permanent redirect\n this.numConsecutiveRedirects++;\n // To prevent circular redirects\n if (this.numConsecutiveRedirects < 10) {\n if (restError.response && restError.response.headers) {\n const location = restError.response.headers.get(\"location\");\n if (location) {\n // Update sender URL\n this.handlePermanentRedirect(location);\n // Send to redirect endpoint as HTTPs library doesn't handle redirect automatically\n return this.exportEnvelopes(envelopes);\n }\n }\n } else {\n const redirectError = new Error(\"Circular redirect\");\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countException(redirectError);\n this.customerSDKStatsMetrics?.countDroppedItems(\n envelopes,\n DropCode.CLIENT_EXCEPTION,\n redirectError.message,\n ExceptionType.CLIENT_EXCEPTION,\n );\n }\n return this.buildExportResult({ code: ExportResultCode.FAILED, error: redirectError });\n }\n } else if (\n restError.statusCode &&\n isRetriable(restError.statusCode) &&\n !this.isStatsbeatSender\n ) {\n this.networkStatsbeatMetrics?.countRetry(restError.statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, restError.statusCode);\n return this.persist(envelopes);\n } else if (\n restError.statusCode === 400 &&\n restError.message.includes(\"Invalid instrumentation key\")\n ) {\n // Invalid instrumentation key, shutdown statsbeat, fail silently\n this.shutdownStatsbeat();\n return { code: ExportResultCode.SUCCESS };\n } else if (\n restError.statusCode &&\n this.isStatsbeatSender &&\n isStatsbeatShutdownStatus(restError.statusCode)\n ) {\n // If the status code is a shutdown status code for statsbeat, shutdown statsbeat and fail silently\n this.incrementStatsbeatFailure();\n return { code: ExportResultCode.SUCCESS };\n }\n\n // For retriable REST errors\n if (this.isRetriableRestError(restError) && !this.isStatsbeatSender) {\n if (this.customerSDKStatsMetrics?.isTimeoutError(restError) && !this.isStatsbeatSender) {\n this.customerSDKStatsMetrics?.countRetryItems(\n envelopes,\n RetryCode.CLIENT_TIMEOUT,\n \"timeout_exception\",\n ExceptionType.TIMEOUT_EXCEPTION,\n );\n diag.error(\"Request timed out. Error message:\", restError.message);\n } else if (restError.statusCode) {\n this.networkStatsbeatMetrics?.countRetry(restError.statusCode);\n this.customerSDKStatsMetrics?.countRetryItems(envelopes, restError.statusCode);\n }\n diag.error(\n \"Retrying due to transient client side error. Error message:\",\n restError.message,\n );\n return this.persist(envelopes);\n }\n // For non-retriable REST errors or client exceptions\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countException(restError);\n this.customerSDKStatsMetrics?.countDroppedItems(\n envelopes,\n DropCode.CLIENT_EXCEPTION,\n restError.message,\n );\n diag.error(\n \"Envelopes could not be exported and are not retriable. Error message:\",\n restError.message,\n );\n }\n return this.buildExportResult({ code: ExportResultCode.FAILED, error: restError });\n }\n }\n\n /**\n * Persist envelopes to disk\n */\n private async persist(envelopes: unknown[]): Promise<ExportResult> {\n try {\n const success = await this.persister.push(envelopes);\n return success\n ? { code: ExportResultCode.SUCCESS }\n : this.buildExportResult({\n code: ExportResultCode.FAILED,\n error: new Error(\"Failed to persist envelope in disk.\"),\n });\n } catch (ex: any) {\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countWriteFailure();\n if (this.disableOfflineStorage && envelopes) {\n this.customerSDKStatsMetrics?.countDroppedItems(\n envelopes as Envelope[],\n DropCode.CLIENT_STORAGE_DISABLED,\n );\n }\n }\n return this.buildExportResult({ code: ExportResultCode.FAILED, error: ex });\n }\n }\n\n /**\n * Disable collection of statsbeat metrics after max failures\n */\n private incrementStatsbeatFailure(): void {\n this.statsbeatFailureCount++;\n if (this.statsbeatFailureCount > MAX_STATSBEAT_FAILURES) {\n this.shutdownStatsbeat();\n }\n }\n\n /**\n * Shutdown statsbeat metrics\n */\n private shutdownStatsbeat(): void {\n if (this.networkStatsbeatMetrics) {\n this.networkStatsbeatMetrics.shutdown();\n }\n if (this.longIntervalStatsbeatMetrics) {\n this.longIntervalStatsbeatMetrics?.shutdown();\n }\n if (this.customerSDKStatsMetrics) {\n this.customerSDKStatsMetrics.shutdown();\n }\n this.statsbeatFailureCount = 0;\n }\n\n private async sendFirstPersistedFile(): Promise<void> {\n const envelopes = (await this.persister.shift()) as Envelope[] | null;\n try {\n if (envelopes) {\n await this.send(envelopes);\n }\n } catch (err: any) {\n if (!this.isStatsbeatSender) {\n this.networkStatsbeatMetrics?.countReadFailure();\n }\n diag.warn(`Failed to fetch persisted file`, err);\n }\n }\n\n private isRetriableRestError(error: RestError): boolean {\n const restErrorTypes: string[] = Object.values(RetriableRestErrorTypes);\n if (error && error.code && restErrorTypes.includes(error.code)) {\n return true;\n }\n return false;\n }\n\n // Silence noisy failures from statsbeat OTel metric readers unless logging is explicitly enabled\n private buildExportResult(result: ExportResult): ExportResult {\n const shouldSurfaceStatsbeatFailures = !!process.env[ENV_APPLICATIONINSIGHTS_SDK_STATS_LOGGING];\n if (this.isStatsbeatSender && result.code === ExportResultCode.FAILED) {\n return shouldSurfaceStatsbeatFailures ? result : { code: ExportResultCode.SUCCESS };\n }\n return result;\n }\n}\n"]}
@@ -34,4 +34,19 @@ export declare class FileSystemPersist implements PersistentStorage {
34
34
  private _storeToDisk;
35
35
  private _fileCleanupTask;
36
36
  }
37
+ /**
38
+ * Return the deterministic local storage path for a given instrumentation key.
39
+ *
40
+ * On shared Linux hosts the first user to create `/tmp/Microsoft/AzureMonitor` can
41
+ * block others because the directory inherits that user's `umask`. This is avoided by
42
+ * inserting a hash of the instrumentation key, user name, process name, and
43
+ * application directory, giving each user their own subdirectory, e.g.
44
+ * `/tmp/Microsoft-AzureMonitor-1234...../opentelemetry-nodejs-<ikey>`.
45
+ *
46
+ * @param instrumentationKey - Application Insights instrumentation key.
47
+ * @param storageDirectory - Optional custom storage directory path. If not provided, system temp directory is used.
48
+ * @returns Absolute path to the storage directory.
49
+ * @internal
50
+ */
51
+ export declare function getStorageDirectory(instrumentationKey: string, storageDirectory: string | undefined): string;
37
52
  //# sourceMappingURL=fileSystemPersist.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileSystemPersist.d.ts","sourceRoot":"","sources":["../../../../../src/platform/nodejs/persist/fileSystemPersist.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAI7F;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,iBAAiB;IAevD,OAAO,CAAC,QAAQ,CAAC;IACjB,OAAO,CAAC,wBAAwB,CAAC;IAfnC,MAAM,CAAC,cAAc,SAAwB;IAC7C,MAAM,CAAC,eAAe,SAAc;IAEpC,oBAAoB,SAA2B;IAC/C,cAAc,SAAkB;IAChC,cAAc,EAAE,MAAM,CAAc;IAEpC,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,mBAAmB,CAAS;gBAGlC,kBAAkB,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,2BAA2B,YAAA,EACtC,wBAAwB,CAAC,EAAE,uBAAuB,YAAA;IAyC5D,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBlC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAkB/B;;;OAGG;YACW,mBAAmB;IA8BjC;;;;;OAKG;YACW,YAAY;YAwDZ,gBAAgB;CA+B/B"}
1
+ {"version":3,"file":"fileSystemPersist.d.ts","sourceRoot":"","sources":["../../../../../src/platform/nodejs/persist/fileSystemPersist.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAG3D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AAI7F;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,iBAAiB;IAevD,OAAO,CAAC,QAAQ,CAAC;IACjB,OAAO,CAAC,wBAAwB,CAAC;IAfnC,MAAM,CAAC,cAAc,SAA2B;IAChD,MAAM,CAAC,eAAe,SAAc;IAEpC,oBAAoB,SAA2B;IAC/C,cAAc,SAAkB;IAChC,cAAc,EAAE,MAAM,CAAc;IAEpC,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,mBAAmB,CAAS;gBAGlC,kBAAkB,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,2BAA2B,YAAA,EACtC,wBAAwB,CAAC,EAAE,uBAAuB,YAAA;IAuC5D,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBlC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAkB/B;;;OAGG;YACW,mBAAmB;IA8BjC;;;;;OAKG;YACW,YAAY;YAwDZ,gBAAgB;CA+B/B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,kBAAkB,EAAE,MAAM,EAC1B,gBAAgB,EAAE,MAAM,GAAG,SAAS,GACnC,MAAM,CA+CR"}
@@ -3,8 +3,10 @@
3
3
  // Licensed under the MIT License.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
5
  exports.FileSystemPersist = void 0;
6
+ exports.getStorageDirectory = getStorageDirectory;
6
7
  const node_os_1 = require("node:os");
7
8
  const node_path_1 = require("node:path");
9
+ const node_crypto_1 = require("node:crypto");
8
10
  const api_1 = require("@opentelemetry/api");
9
11
  const fileAccessControl_js_1 = require("./fileAccessControl.js");
10
12
  const fileSystemHelpers_js_1 = require("./fileSystemHelpers.js");
@@ -17,7 +19,7 @@ const types_js_1 = require("../../../export/statsbeat/types.js");
17
19
  class FileSystemPersist {
18
20
  _options;
19
21
  _customerSDKStatsMetrics;
20
- static TEMPDIR_PREFIX = "ot-azure-exporter-";
22
+ static TEMPDIR_PREFIX = "opentelemetry-nodejs-";
21
23
  static FILENAME_SUFFIX = ".ai.json";
22
24
  fileRetemptionPeriod = 2 * 24 * 60 * 60 * 1000; // 2 days
23
25
  cleanupTimeOut = 60 * 60 * 1000; // 1 hour
@@ -45,7 +47,7 @@ class FileSystemPersist {
45
47
  api_1.diag.error(`No instrumentation key was provided to FileSystemPersister. Files will not be persisted`);
46
48
  }
47
49
  if (this._enabled) {
48
- this._tempDirectory = (0, node_path_1.join)(this._options?.storageDirectory || (0, node_os_1.tmpdir)(), "Microsoft", "AzureMonitor", FileSystemPersist.TEMPDIR_PREFIX + this._instrumentationKey);
50
+ this._tempDirectory = getStorageDirectory(this._instrumentationKey, this._options?.storageDirectory);
49
51
  // Starts file cleanup task
50
52
  if (!this._fileCleanupTimer) {
51
53
  this._fileCleanupTimer = setTimeout(() => {
@@ -202,4 +204,65 @@ class FileSystemPersist {
202
204
  }
203
205
  }
204
206
  exports.FileSystemPersist = FileSystemPersist;
207
+ /**
208
+ * Return the deterministic local storage path for a given instrumentation key.
209
+ *
210
+ * On shared Linux hosts the first user to create `/tmp/Microsoft/AzureMonitor` can
211
+ * block others because the directory inherits that user's `umask`. This is avoided by
212
+ * inserting a hash of the instrumentation key, user name, process name, and
213
+ * application directory, giving each user their own subdirectory, e.g.
214
+ * `/tmp/Microsoft-AzureMonitor-1234...../opentelemetry-nodejs-<ikey>`.
215
+ *
216
+ * @param instrumentationKey - Application Insights instrumentation key.
217
+ * @param storageDirectory - Optional custom storage directory path. If not provided, system temp directory is used.
218
+ * @returns Absolute path to the storage directory.
219
+ * @internal
220
+ */
221
+ function getStorageDirectory(instrumentationKey, storageDirectory) {
222
+ let userSegment;
223
+ let processName;
224
+ let applicationDirectory;
225
+ try {
226
+ const user = (0, node_os_1.userInfo)();
227
+ userSegment = user.username;
228
+ }
229
+ catch (error) {
230
+ userSegment = "";
231
+ }
232
+ if (process.title.length > 0) {
233
+ processName = process.title;
234
+ }
235
+ else {
236
+ processName = "";
237
+ }
238
+ const applicationDir = (0, node_path_1.dirname)(process.cwd() || process.argv[1]);
239
+ if (applicationDir) {
240
+ applicationDirectory = applicationDir;
241
+ }
242
+ else {
243
+ applicationDirectory = "";
244
+ }
245
+ const hash_input = `${instrumentationKey}|${userSegment}|${processName}|${applicationDirectory}`;
246
+ let subDirectory;
247
+ try {
248
+ subDirectory = (0, node_crypto_1.createHash)("sha256").update(hash_input).digest("hex");
249
+ }
250
+ catch (error) {
251
+ let hash = 5381;
252
+ for (let i = 0; i < hash_input.length; i++) {
253
+ const char = hash_input.charCodeAt(i);
254
+ hash = (hash << 5) + hash + char;
255
+ hash = hash & hash;
256
+ }
257
+ subDirectory = Math.abs(hash).toString(16);
258
+ }
259
+ let sharedRoot;
260
+ if (storageDirectory) {
261
+ sharedRoot = storageDirectory;
262
+ }
263
+ else {
264
+ sharedRoot = (0, node_os_1.tmpdir)();
265
+ }
266
+ return (0, node_path_1.join)(sharedRoot, "Microsoft-AzureMonitor-" + subDirectory, FileSystemPersist.TEMPDIR_PREFIX + instrumentationKey);
267
+ }
205
268
  //# sourceMappingURL=fileSystemPersist.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileSystemPersist.js","sourceRoot":"","sources":["../../../../../src/platform/nodejs/persist/fileSystemPersist.ts"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;;;AAElC,qCAAiC;AACjC,yCAA2C;AAC3C,4CAA0C;AAE1C,iEAA2D;AAC3D,iEAAmF;AAEnF,+CAA8E;AAE9E,iEAA6E;AAG7E;;;GAGG;AACH,MAAa,iBAAiB;IAelB;IACA;IAfV,MAAM,CAAC,cAAc,GAAG,oBAAoB,CAAC;IAC7C,MAAM,CAAC,eAAe,GAAG,UAAU,CAAC;IAEpC,oBAAoB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;IACzD,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;IAC1C,cAAc,GAAW,UAAU,CAAC,CAAC,QAAQ;IAErC,QAAQ,CAAU;IAClB,cAAc,GAAW,EAAE,CAAC;IAC5B,iBAAiB,GAA0B,IAAI,CAAC;IAChD,mBAAmB,CAAS;IAEpC,YACE,kBAA0B,EAClB,QAAsC,EACtC,wBAAkD;QADlD,aAAQ,GAAR,QAAQ,CAA8B;QACtC,6BAAwB,GAAxB,wBAAwB,CAA0B;QAE1D,IAAI,CAAC,mBAAmB,GAAG,kBAAkB,CAAC;QAC9C,IAAI,IAAI,CAAC,QAAQ,EAAE,qBAAqB,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,wCAAiB,CAAC,mBAAmB,EAAE,CAAC;QAExC,IAAI,CAAC,wCAAiB,CAAC,2BAA2B,EAAE,CAAC;YACnD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,UAAI,CAAC,KAAK,CACR,wFAAwF,CACzF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,UAAI,CAAC,KAAK,CACR,yFAAyF,CAC1F,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,cAAc,GAAG,IAAA,gBAAI,EACxB,IAAI,CAAC,QAAQ,EAAE,gBAAgB,IAAI,IAAA,gBAAM,GAAE,EAC3C,WAAW,EACX,cAAc,EACd,iBAAiB,CAAC,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAC5D,CAAC;YAEF,2BAA2B;YAC3B,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC5B,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvC,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC1B,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;gBACxB,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,KAAgB;QACnB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,UAAI,CAAC,KAAK,CAAC,qCAAqC,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YACpE,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAmB,CAAC,CAAC;QACvE,CAAC;QACD,8EAA8E;QAC9E,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,qBAAqB,EAAE,CAAC;YAC1C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,OAAO,CAAC,KAAK,CAAC,CAAC;YACjB,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,UAAI,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACvD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAChD,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;gBAC7C,CAAC;YACH,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,UAAI,CAAC,KAAK,CAAC,+BAA+B,EAAE,CAAC,CAAC,CAAC;YACjD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,mBAAmB;QAC/B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC9C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,MAAM,IAAA,kBAAO,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACrD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACnC,IAAA,oBAAQ,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,eAAe,CAAC,CACxD,CAAC;gBACF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,OAAO,IAAI,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACN,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;oBAC3B,MAAM,QAAQ,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;oBACtD,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAQ,EAAC,QAAQ,CAAC,CAAC;oBACzC,kDAAkD;oBAClD,MAAM,IAAA,iBAAM,EAAC,QAAQ,CAAC,CAAC;oBACvB,OAAO,OAAO,CAAC;gBACjB,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACxB,yDAAyD;gBACzD,OAAO,IAAI,CAAC;YACd,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,CAAC;YACV,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,YAAY,CAAC,OAAe,EAAE,SAAqB;QAC/D,IAAI,CAAC;YACH,MAAM,IAAA,uCAAgB,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,sDAAsD;YACtD,IAAI,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,EAAE,IAAI,KAAK,OAAO,EAAE,CAAC;gBACxD,IAAI,CAAC,wBAAwB,EAAE,iBAAiB,CAAC,SAAS,EAAE,mBAAQ,CAAC,eAAe,CAAC,CAAC;gBACtF,UAAI,CAAC,IAAI,CACP,wDAAwD,IAAI,CAAC,cAAc,EAAE,EAC7E,KAAK,EAAE,OAAO,CACf,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,UAAI,CAAC,IAAI,CAAC,2CAA2C,EAAE,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;YACjF,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAA,8CAAuB,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAChE,IAAI,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC/B,4FAA4F;gBAC5F,IAAI,CAAC,wBAAwB,EAAE,iBAAiB,CAC9C,SAAS,EACT,mBAAQ,CAAC,2BAA2B,CACrC,CAAC;gBACF,UAAI,CAAC,IAAI,CACP,gFAAgF,IAAI,EAAE,CACvF,CAAC;gBACF,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,UAAI,CAAC,IAAI,CAAC,sDAAsD,EAAE,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;YAC1F,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,iBAAiB,CAAC,eAAe,EAAE,CAAC;QAC/E,MAAM,YAAY,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;QAEzD,4DAA4D;QAC5D,UAAI,CAAC,IAAI,CAAC,2BAA2B,YAAY,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC;YACH,MAAM,IAAA,oBAAS,EAAC,YAAY,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,UAAe,EAAE,CAAC;YACzB,2FAA2F;YAC3F,IAAI,CAAC,wBAAwB,EAAE,iBAAiB,CAC9C,SAAS,EACT,mBAAQ,CAAC,gBAAgB,EACzB,UAAU,EAAE,OAAO,EACnB,wBAAa,CAAC,iBAAiB,CAChC,CAAC;YACF,UAAI,CAAC,IAAI,CAAC,+CAA+C,EAAE,UAAU,CAAC,CAAC;YACvE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAA,eAAI,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC9C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,SAAS,GAAG,MAAM,IAAA,kBAAO,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC;gBACrD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACnC,IAAA,oBAAQ,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,eAAe,CAAC,CACxD,CAAC;gBACF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,OAAO,KAAK,CAAC;gBACf,CAAC;qBAAM,CAAC;oBACN,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;wBAC3B,mBAAmB;wBACnB,MAAM,gBAAgB,GAAS,IAAI,IAAI,CACrC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAC3D,CAAC;wBACF,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,gBAAgB,CAAC;wBACrF,IAAI,OAAO,EAAE,CAAC;4BACZ,MAAM,QAAQ,GAAG,IAAA,gBAAI,EAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;4BACjD,MAAM,IAAA,iBAAM,EAAC,QAAQ,CAAC,CAAC;wBACzB,CAAC;oBACH,CAAC,CAAC,CAAC;oBACH,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,UAAI,CAAC,IAAI,CAAC,yDAAyD,EAAE,KAAK,CAAC,CAAC;YAC5E,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;;AAzNH,8CA0NC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { tmpdir } from \"node:os\";\nimport { basename, join } from \"node:path\";\nimport { diag } from \"@opentelemetry/api\";\nimport type { PersistentStorage } from \"../../../types.js\";\nimport { FileAccessControl } from \"./fileAccessControl.js\";\nimport { confirmDirExists, getShallowDirectorySize } from \"./fileSystemHelpers.js\";\nimport type { AzureMonitorExporterOptions } from \"../../../config.js\";\nimport { readdir, readFile, stat, unlink, writeFile } from \"node:fs/promises\";\nimport type { CustomerSDKStatsMetrics } from \"../../../export/statsbeat/customerSDKStats.js\";\nimport { DropCode, ExceptionType } from \"../../../export/statsbeat/types.js\";\nimport type { TelemetryItem as Envelope } from \"../../../generated/index.js\";\n\n/**\n * File system persist class.\n * @internal\n */\nexport class FileSystemPersist implements PersistentStorage {\n static TEMPDIR_PREFIX = \"ot-azure-exporter-\";\n static FILENAME_SUFFIX = \".ai.json\";\n\n fileRetemptionPeriod = 2 * 24 * 60 * 60 * 1000; // 2 days\n cleanupTimeOut = 60 * 60 * 1000; // 1 hour\n maxBytesOnDisk: number = 50_000_000; // ~50MB\n\n private _enabled: boolean;\n private _tempDirectory: string = \"\";\n private _fileCleanupTimer: NodeJS.Timeout | null = null;\n private _instrumentationKey: string;\n\n constructor(\n instrumentationKey: string,\n private _options?: AzureMonitorExporterOptions,\n private _customerSDKStatsMetrics?: CustomerSDKStatsMetrics,\n ) {\n this._instrumentationKey = instrumentationKey;\n if (this._options?.disableOfflineStorage) {\n this._enabled = false;\n return;\n }\n this._enabled = true;\n FileAccessControl.checkFileProtection();\n\n if (!FileAccessControl.OS_PROVIDES_FILE_PROTECTION) {\n this._enabled = false;\n diag.error(\n \"Sufficient file protection capabilities were not detected. Files will not be persisted\",\n );\n }\n\n if (!this._instrumentationKey) {\n this._enabled = false;\n diag.error(\n `No instrumentation key was provided to FileSystemPersister. Files will not be persisted`,\n );\n }\n if (this._enabled) {\n this._tempDirectory = join(\n this._options?.storageDirectory || tmpdir(),\n \"Microsoft\",\n \"AzureMonitor\",\n FileSystemPersist.TEMPDIR_PREFIX + this._instrumentationKey,\n );\n\n // Starts file cleanup task\n if (!this._fileCleanupTimer) {\n this._fileCleanupTimer = setTimeout(() => {\n this._fileCleanupTask();\n }, this.cleanupTimeOut);\n this._fileCleanupTimer.unref();\n }\n }\n }\n\n push(value: unknown[]): Promise<boolean> {\n if (this._enabled) {\n diag.debug(\"Pushing value to persistent storage\", value.toString());\n return this._storeToDisk(JSON.stringify(value), value as Envelope[]);\n }\n // Only return a false promise if the SDK isn't set to disable offline storage\n if (!this._options?.disableOfflineStorage) {\n return new Promise((resolve) => {\n resolve(false);\n });\n }\n return new Promise((resolve) => {\n resolve(true);\n });\n }\n\n async shift(): Promise<unknown> {\n if (this._enabled) {\n diag.debug(\"Searching for filesystem persisted files\");\n try {\n const buffer = await this._getFirstFileOnDisk();\n if (buffer) {\n return JSON.parse(buffer.toString(\"utf8\"));\n }\n } catch (e: any) {\n diag.debug(\"Failed to read persisted file\", e);\n }\n return null;\n }\n return new Promise((resolve) => {\n resolve(null);\n });\n }\n\n /**\n * Check for temp telemetry files\n * reads the first file if exist, deletes it and tries to send its load\n */\n private async _getFirstFileOnDisk(): Promise<Buffer | null> {\n try {\n const stats = await stat(this._tempDirectory);\n if (stats.isDirectory()) {\n const origFiles = await readdir(this._tempDirectory);\n const files = origFiles.filter((f) =>\n basename(f).includes(FileSystemPersist.FILENAME_SUFFIX),\n );\n if (files.length === 0) {\n return null;\n } else {\n const firstFile = files[0];\n const filePath = join(this._tempDirectory, firstFile);\n const payload = await readFile(filePath);\n // delete the file first to prevent double sending\n await unlink(filePath);\n return payload;\n }\n }\n return null;\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n // File does not exist -- return null instead of throwing\n return null;\n } else {\n throw e;\n }\n }\n }\n\n /**\n * Stores telemetry data to disk.\n * @param payload - The telemetry data to store.\n * @param envelopeLength -The length of the telemetry envelope.\n * @returns A promise that resolves to true if the data was stored successfully, false otherwise.\n */\n private async _storeToDisk(payload: string, envelopes: Envelope[]): Promise<boolean> {\n try {\n await confirmDirExists(this._tempDirectory);\n } catch (error: any) {\n // Check if error is due to permission/readonly issues\n if (error?.code === \"EACCES\" || error?.code === \"EPERM\") {\n this._customerSDKStatsMetrics?.countDroppedItems(envelopes, DropCode.CLIENT_READONLY);\n diag.warn(\n `Permission denied while checking/creating directory: ${this._tempDirectory}`,\n error?.message,\n );\n } else {\n diag.warn(`Error while checking/creating directory: `, error && error.message);\n }\n return false;\n }\n\n try {\n const size = await getShallowDirectorySize(this._tempDirectory);\n if (size > this.maxBytesOnDisk) {\n // If the directory size exceeds the max limit, we send customer SDK Stats and warn the user\n this._customerSDKStatsMetrics?.countDroppedItems(\n envelopes,\n DropCode.CLIENT_PERSISTENCE_CAPACITY,\n );\n diag.warn(\n `Not saving data due to max size limit being met. Directory size in bytes is: ${size}`,\n );\n return false;\n }\n } catch (error: any) {\n diag.warn(`Error while checking size of persistence directory: `, error && error.message);\n return false;\n }\n\n const fileName = `${new Date().getTime()}${FileSystemPersist.FILENAME_SUFFIX}`;\n const fileFullPath = join(this._tempDirectory, fileName);\n\n // Mode 600 is w/r for creator and no read access for others\n diag.info(`saving data to disk at: ${fileFullPath}`);\n try {\n await writeFile(fileFullPath, payload, { mode: 0o600 });\n } catch (writeError: any) {\n // If the envelopes cannot be written to disk, we send customer SDK Stats and warn the user\n this._customerSDKStatsMetrics?.countDroppedItems(\n envelopes,\n DropCode.CLIENT_EXCEPTION,\n writeError?.message,\n ExceptionType.STORAGE_EXCEPTION,\n );\n diag.warn(`Error writing file to persistent file storage`, writeError);\n return false;\n }\n return true;\n }\n\n private async _fileCleanupTask(): Promise<boolean> {\n try {\n const stats = await stat(this._tempDirectory);\n if (stats.isDirectory()) {\n const origFiles = await readdir(this._tempDirectory);\n const files = origFiles.filter((f) =>\n basename(f).includes(FileSystemPersist.FILENAME_SUFFIX),\n );\n if (files.length === 0) {\n return false;\n } else {\n files.forEach(async (file) => {\n // Check expiration\n const fileCreationDate: Date = new Date(\n parseInt(file.split(FileSystemPersist.FILENAME_SUFFIX)[0]),\n );\n const expired = new Date(+new Date() - this.fileRetemptionPeriod) > fileCreationDate;\n if (expired) {\n const filePath = join(this._tempDirectory, file);\n await unlink(filePath);\n }\n });\n return true;\n }\n }\n return false;\n } catch (error: any) {\n diag.info(`Failed cleanup of persistent file storage expired files`, error);\n return false;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"fileSystemPersist.js","sourceRoot":"","sources":["../../../../../src/platform/nodejs/persist/fileSystemPersist.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { tmpdir, userInfo } from \"node:os\";\nimport { basename, join, dirname } from \"node:path\";\nimport { createHash } from \"node:crypto\";\nimport { diag } from \"@opentelemetry/api\";\nimport type { PersistentStorage } from \"../../../types.js\";\nimport { FileAccessControl } from \"./fileAccessControl.js\";\nimport { confirmDirExists, getShallowDirectorySize } from \"./fileSystemHelpers.js\";\nimport type { AzureMonitorExporterOptions } from \"../../../config.js\";\nimport { readdir, readFile, stat, unlink, writeFile } from \"node:fs/promises\";\nimport type { CustomerSDKStatsMetrics } from \"../../../export/statsbeat/customerSDKStats.js\";\nimport { DropCode, ExceptionType } from \"../../../export/statsbeat/types.js\";\nimport type { TelemetryItem as Envelope } from \"../../../generated/index.js\";\n\n/**\n * File system persist class.\n * @internal\n */\nexport class FileSystemPersist implements PersistentStorage {\n static TEMPDIR_PREFIX = \"opentelemetry-nodejs-\";\n static FILENAME_SUFFIX = \".ai.json\";\n\n fileRetemptionPeriod = 2 * 24 * 60 * 60 * 1000; // 2 days\n cleanupTimeOut = 60 * 60 * 1000; // 1 hour\n maxBytesOnDisk: number = 50_000_000; // ~50MB\n\n private _enabled: boolean;\n private _tempDirectory: string = \"\";\n private _fileCleanupTimer: NodeJS.Timeout | null = null;\n private _instrumentationKey: string;\n\n constructor(\n instrumentationKey: string,\n private _options?: AzureMonitorExporterOptions,\n private _customerSDKStatsMetrics?: CustomerSDKStatsMetrics,\n ) {\n this._instrumentationKey = instrumentationKey;\n if (this._options?.disableOfflineStorage) {\n this._enabled = false;\n return;\n }\n this._enabled = true;\n FileAccessControl.checkFileProtection();\n\n if (!FileAccessControl.OS_PROVIDES_FILE_PROTECTION) {\n this._enabled = false;\n diag.error(\n \"Sufficient file protection capabilities were not detected. Files will not be persisted\",\n );\n }\n\n if (!this._instrumentationKey) {\n this._enabled = false;\n diag.error(\n `No instrumentation key was provided to FileSystemPersister. Files will not be persisted`,\n );\n }\n if (this._enabled) {\n this._tempDirectory = getStorageDirectory(\n this._instrumentationKey,\n this._options?.storageDirectory,\n );\n\n // Starts file cleanup task\n if (!this._fileCleanupTimer) {\n this._fileCleanupTimer = setTimeout(() => {\n this._fileCleanupTask();\n }, this.cleanupTimeOut);\n this._fileCleanupTimer.unref();\n }\n }\n }\n\n push(value: unknown[]): Promise<boolean> {\n if (this._enabled) {\n diag.debug(\"Pushing value to persistent storage\", value.toString());\n return this._storeToDisk(JSON.stringify(value), value as Envelope[]);\n }\n // Only return a false promise if the SDK isn't set to disable offline storage\n if (!this._options?.disableOfflineStorage) {\n return new Promise((resolve) => {\n resolve(false);\n });\n }\n return new Promise((resolve) => {\n resolve(true);\n });\n }\n\n async shift(): Promise<unknown> {\n if (this._enabled) {\n diag.debug(\"Searching for filesystem persisted files\");\n try {\n const buffer = await this._getFirstFileOnDisk();\n if (buffer) {\n return JSON.parse(buffer.toString(\"utf8\"));\n }\n } catch (e: any) {\n diag.debug(\"Failed to read persisted file\", e);\n }\n return null;\n }\n return new Promise((resolve) => {\n resolve(null);\n });\n }\n\n /**\n * Check for temp telemetry files\n * reads the first file if exist, deletes it and tries to send its load\n */\n private async _getFirstFileOnDisk(): Promise<Buffer | null> {\n try {\n const stats = await stat(this._tempDirectory);\n if (stats.isDirectory()) {\n const origFiles = await readdir(this._tempDirectory);\n const files = origFiles.filter((f) =>\n basename(f).includes(FileSystemPersist.FILENAME_SUFFIX),\n );\n if (files.length === 0) {\n return null;\n } else {\n const firstFile = files[0];\n const filePath = join(this._tempDirectory, firstFile);\n const payload = await readFile(filePath);\n // delete the file first to prevent double sending\n await unlink(filePath);\n return payload;\n }\n }\n return null;\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n // File does not exist -- return null instead of throwing\n return null;\n } else {\n throw e;\n }\n }\n }\n\n /**\n * Stores telemetry data to disk.\n * @param payload - The telemetry data to store.\n * @param envelopeLength -The length of the telemetry envelope.\n * @returns A promise that resolves to true if the data was stored successfully, false otherwise.\n */\n private async _storeToDisk(payload: string, envelopes: Envelope[]): Promise<boolean> {\n try {\n await confirmDirExists(this._tempDirectory);\n } catch (error: any) {\n // Check if error is due to permission/readonly issues\n if (error?.code === \"EACCES\" || error?.code === \"EPERM\") {\n this._customerSDKStatsMetrics?.countDroppedItems(envelopes, DropCode.CLIENT_READONLY);\n diag.warn(\n `Permission denied while checking/creating directory: ${this._tempDirectory}`,\n error?.message,\n );\n } else {\n diag.warn(`Error while checking/creating directory: `, error && error.message);\n }\n return false;\n }\n\n try {\n const size = await getShallowDirectorySize(this._tempDirectory);\n if (size > this.maxBytesOnDisk) {\n // If the directory size exceeds the max limit, we send customer SDK Stats and warn the user\n this._customerSDKStatsMetrics?.countDroppedItems(\n envelopes,\n DropCode.CLIENT_PERSISTENCE_CAPACITY,\n );\n diag.warn(\n `Not saving data due to max size limit being met. Directory size in bytes is: ${size}`,\n );\n return false;\n }\n } catch (error: any) {\n diag.warn(`Error while checking size of persistence directory: `, error && error.message);\n return false;\n }\n\n const fileName = `${new Date().getTime()}${FileSystemPersist.FILENAME_SUFFIX}`;\n const fileFullPath = join(this._tempDirectory, fileName);\n\n // Mode 600 is w/r for creator and no read access for others\n diag.info(`saving data to disk at: ${fileFullPath}`);\n try {\n await writeFile(fileFullPath, payload, { mode: 0o600 });\n } catch (writeError: any) {\n // If the envelopes cannot be written to disk, we send customer SDK Stats and warn the user\n this._customerSDKStatsMetrics?.countDroppedItems(\n envelopes,\n DropCode.CLIENT_EXCEPTION,\n writeError?.message,\n ExceptionType.STORAGE_EXCEPTION,\n );\n diag.warn(`Error writing file to persistent file storage`, writeError);\n return false;\n }\n return true;\n }\n\n private async _fileCleanupTask(): Promise<boolean> {\n try {\n const stats = await stat(this._tempDirectory);\n if (stats.isDirectory()) {\n const origFiles = await readdir(this._tempDirectory);\n const files = origFiles.filter((f) =>\n basename(f).includes(FileSystemPersist.FILENAME_SUFFIX),\n );\n if (files.length === 0) {\n return false;\n } else {\n files.forEach(async (file) => {\n // Check expiration\n const fileCreationDate: Date = new Date(\n parseInt(file.split(FileSystemPersist.FILENAME_SUFFIX)[0]),\n );\n const expired = new Date(+new Date() - this.fileRetemptionPeriod) > fileCreationDate;\n if (expired) {\n const filePath = join(this._tempDirectory, file);\n await unlink(filePath);\n }\n });\n return true;\n }\n }\n return false;\n } catch (error: any) {\n diag.info(`Failed cleanup of persistent file storage expired files`, error);\n return false;\n }\n }\n}\n\n/**\n * Return the deterministic local storage path for a given instrumentation key.\n *\n * On shared Linux hosts the first user to create `/tmp/Microsoft/AzureMonitor` can\n * block others because the directory inherits that user's `umask`. This is avoided by\n * inserting a hash of the instrumentation key, user name, process name, and\n * application directory, giving each user their own subdirectory, e.g.\n * `/tmp/Microsoft-AzureMonitor-1234...../opentelemetry-nodejs-<ikey>`.\n *\n * @param instrumentationKey - Application Insights instrumentation key.\n * @param storageDirectory - Optional custom storage directory path. If not provided, system temp directory is used.\n * @returns Absolute path to the storage directory.\n * @internal\n */\nexport function getStorageDirectory(\n instrumentationKey: string,\n storageDirectory: string | undefined,\n): string {\n let userSegment: string;\n let processName: string;\n let applicationDirectory: string;\n try {\n const user = userInfo();\n userSegment = user.username;\n } catch (error) {\n userSegment = \"\";\n }\n if (process.title.length > 0) {\n processName = process.title;\n } else {\n processName = \"\";\n }\n const applicationDir = dirname(process.cwd() || process.argv[1]);\n if (applicationDir) {\n applicationDirectory = applicationDir;\n } else {\n applicationDirectory = \"\";\n }\n const hash_input = `${instrumentationKey}|${userSegment}|${processName}|${applicationDirectory}`;\n\n let subDirectory: string;\n try {\n subDirectory = createHash(\"sha256\").update(hash_input).digest(\"hex\");\n } catch (error) {\n let hash = 5381;\n for (let i = 0; i < hash_input.length; i++) {\n const char = hash_input.charCodeAt(i);\n hash = (hash << 5) + hash + char;\n hash = hash & hash;\n }\n subDirectory = Math.abs(hash).toString(16);\n }\n\n let sharedRoot: string;\n if (storageDirectory) {\n sharedRoot = storageDirectory;\n } else {\n sharedRoot = tmpdir();\n }\n return join(\n sharedRoot,\n \"Microsoft-AzureMonitor-\" + subDirectory,\n FileSystemPersist.TEMPDIR_PREFIX + instrumentationKey,\n );\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.52.13"
8
+ "packageVersion": "7.55.2"
9
9
  }
10
10
  ]
11
11
  }
@@ -1,6 +1,6 @@
1
1
  import { type Tags } from "../types.js";
2
2
  import type { TelemetryItem as Envelope } from "../generated/index.js";
3
- import type { Resource } from "@opentelemetry/resources";
3
+ import { type Resource } from "@opentelemetry/resources";
4
4
  import type { Attributes, HrTime } from "@opentelemetry/api";
5
5
  import type { AnyValue } from "@opentelemetry/api-logs";
6
6
  export declare function hrTimeToDate(hrTime: HrTime): Date;
@@ -8,7 +8,7 @@ export declare function createTagsFromResource(resource: Resource): Tags;
8
8
  export declare function isSqlDB(dbSystem: string): boolean;
9
9
  export declare function getUrl(attributes: Attributes): string;
10
10
  export declare function getDependencyTarget(attributes: Attributes): string;
11
- export declare function createResourceMetricEnvelope(resource: Resource, instrumentationKey: string): Envelope | undefined;
11
+ export declare function createResourceMetricEnvelope(resource: Resource, instrumentationKey: string, applicationId?: string): Envelope | undefined;
12
12
  export declare function serializeAttribute(value: AnyValue): string;
13
13
  export declare function shouldCreateResourceMetric(): boolean;
14
14
  export declare function isSyntheticSource(attributes: Attributes): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/utils/common.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAmC,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAe,MAAM,uBAAuB,CAAC;AAEpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAaxD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAqB/D;AAmED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAYjD;AAED,wBAAgB,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAkCrD;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAqBlE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,EAClB,kBAAkB,EAAE,MAAM,GACzB,QAAQ,GAAG,SAAS,CAwCtB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAsB1D;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAEjE"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/utils/common.ts"],"names":[],"mappings":"AAgCA,OAAO,EAAmC,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAe,MAAM,uBAAuB,CAAC;AAEpF,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAgBxD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAkB/D;AAmED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAYjD;AAED,wBAAgB,MAAM,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAkCrD;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAqBlE;AAED,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,EAClB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,CAAC,EAAE,MAAM,GACrB,QAAQ,GAAG,SAAS,CA8CtB;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAsB1D;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAEjE"}
@@ -26,17 +26,18 @@ function hrTimeToDate(hrTime) {
26
26
  function createTagsFromResource(resource) {
27
27
  const context = (0, index_js_1.getInstance)();
28
28
  const tags = { ...context.tags };
29
- if (resource && resource.attributes) {
29
+ const attributes = resource?.attributes;
30
+ if (attributes) {
30
31
  tags[index_js_2.KnownContextTagKeys.AiCloudRole] = getCloudRole(resource);
31
32
  tags[index_js_2.KnownContextTagKeys.AiCloudRoleInstance] = getCloudRoleInstance(resource);
32
- if (resource.attributes[semantic_conventions_1.SEMRESATTRS_DEVICE_ID]) {
33
- tags[index_js_2.KnownContextTagKeys.AiDeviceId] = String(resource.attributes[semantic_conventions_1.SEMRESATTRS_DEVICE_ID]);
33
+ if (attributes[semantic_conventions_1.SEMRESATTRS_DEVICE_ID]) {
34
+ tags[index_js_2.KnownContextTagKeys.AiDeviceId] = String(attributes[semantic_conventions_1.SEMRESATTRS_DEVICE_ID]);
34
35
  }
35
- if (resource.attributes[semantic_conventions_1.SEMRESATTRS_DEVICE_MODEL_NAME]) {
36
- tags[index_js_2.KnownContextTagKeys.AiDeviceModel] = String(resource.attributes[semantic_conventions_1.SEMRESATTRS_DEVICE_MODEL_NAME]);
36
+ if (attributes[semantic_conventions_1.SEMRESATTRS_DEVICE_MODEL_NAME]) {
37
+ tags[index_js_2.KnownContextTagKeys.AiDeviceModel] = String(attributes[semantic_conventions_1.SEMRESATTRS_DEVICE_MODEL_NAME]);
37
38
  }
38
- if (resource.attributes[semantic_conventions_1.SEMRESATTRS_SERVICE_VERSION]) {
39
- tags[index_js_2.KnownContextTagKeys.AiApplicationVer] = String(resource.attributes[semantic_conventions_1.SEMRESATTRS_SERVICE_VERSION]);
39
+ if (attributes[semantic_conventions_1.SEMRESATTRS_SERVICE_VERSION]) {
40
+ tags[index_js_2.KnownContextTagKeys.AiApplicationVer] = String(attributes[semantic_conventions_1.SEMRESATTRS_SERVICE_VERSION]);
40
41
  }
41
42
  }
42
43
  return tags;
@@ -182,17 +183,21 @@ function getDependencyTarget(attributes) {
182
183
  }
183
184
  return "";
184
185
  }
185
- function createResourceMetricEnvelope(resource, instrumentationKey) {
186
- if (resource && resource.attributes) {
186
+ function createResourceMetricEnvelope(resource, instrumentationKey, applicationId) {
187
+ const attributes = resource.attributes;
188
+ if (attributes) {
187
189
  const tags = createTagsFromResource(resource);
188
190
  const resourceAttributes = {};
189
- for (const key of Object.keys(resource.attributes)) {
191
+ if (applicationId && !attributes[Constants_js_1.APPLICATION_ID_RESOURCE_KEY]) {
192
+ resourceAttributes[Constants_js_1.APPLICATION_ID_RESOURCE_KEY] = applicationId;
193
+ }
194
+ for (const key of Object.keys(attributes)) {
190
195
  // Avoid duplication ignoring fields already mapped.
191
196
  if (!(key.startsWith("_MS.") ||
192
197
  key === semantic_conventions_1.ATTR_TELEMETRY_SDK_VERSION ||
193
198
  key === semantic_conventions_1.ATTR_TELEMETRY_SDK_LANGUAGE ||
194
199
  key === semantic_conventions_1.ATTR_TELEMETRY_SDK_NAME)) {
195
- resourceAttributes[key] = resource.attributes[key];
200
+ resourceAttributes[key] = attributes[key];
196
201
  }
197
202
  }
198
203
  // Only send event when resource attributes are available