diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 16360bb4..408990b2 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -13,7 +13,6 @@ jobs: strategy: matrix: - # TODO: Enable Node 14.x when we update the pipeline to support AbortController node-version: [18.x] steps: diff --git a/CHANGELOG.md b/CHANGELOG.md index fcb8007c..aa1aa088 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Release History -### 3.13.1 () +### 3.14.0 (2026-02-24) #### Other Changes diff --git a/package-lock.json b/package-lock.json index 107cae39..da86b05b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,20 +1,20 @@ { "name": "applicationinsights", - "version": "3.13.0", + "version": "3.14.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "applicationinsights", - "version": "3.13.0", + "version": "3.14.0", "license": "MIT", "dependencies": { "@azure/core-auth": "^1.9.0", "@azure/functions": "^4.11.2", "@azure/functions-old": "npm:@azure/functions@3.5.1", "@azure/identity": "^4.6.0", - "@azure/monitor-opentelemetry": "^1.15.1", - "@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.38", + "@azure/monitor-opentelemetry": "^1.16.0", + "@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.39", "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.7", "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.208.0", @@ -52,7 +52,7 @@ "typescript": "~4.8.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=18.0.0" } }, "node_modules/@azure/abort-controller": { @@ -213,16 +213,16 @@ } }, "node_modules/@azure/monitor-opentelemetry": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@azure/monitor-opentelemetry/-/monitor-opentelemetry-1.15.1.tgz", - "integrity": "sha512-Ybr8BfypmSt0L3TObjMFxv37B6qYI7TTX/fs9V0hi86LI75ZG2bvPAFr9Dt/L2LaNXaLck3fNVQ/ocuMJid7hQ==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@azure/monitor-opentelemetry/-/monitor-opentelemetry-1.16.0.tgz", + "integrity": "sha512-GUE4kowIKrqxzPjiy/o417jot4n0BILomMbDCeK9lOnLxV0VliccEuz+FJ9BgLWKWswr6H0Q2Nzpcx9GFuLHXw==", "license": "MIT", "dependencies": { "@azure/core-auth": "^1.10.1", "@azure/core-client": "^1.10.1", "@azure/core-rest-pipeline": "^1.22.2", "@azure/logger": "^1.3.0", - "@azure/monitor-opentelemetry-exporter": "1.0.0-beta.38", + "@azure/monitor-opentelemetry-exporter": "1.0.0-beta.39", "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.9", "@microsoft/applicationinsights-web-snippet": "^1.2.3", "@opentelemetry/api": "^1.9.0", @@ -252,9 +252,9 @@ } }, "node_modules/@azure/monitor-opentelemetry-exporter": { - "version": "1.0.0-beta.38", - "resolved": "https://registry.npmjs.org/@azure/monitor-opentelemetry-exporter/-/monitor-opentelemetry-exporter-1.0.0-beta.38.tgz", - "integrity": "sha512-lzY9XpgRwWC94lzeAf2I1YXrP7oMx1B/vn83zoYA5RKW2ZBPzXZ+LUJjYCo/ItzLfT4eMQC80VL4lQC/VknIMA==", + "version": "1.0.0-beta.39", + "resolved": "https://registry.npmjs.org/@azure/monitor-opentelemetry-exporter/-/monitor-opentelemetry-exporter-1.0.0-beta.39.tgz", + "integrity": "sha512-ljvm3PBe5em/kudINq3kA7wzwCQihYn/1HiO1/lKocK68QGahr6qiTwsadBXWJ2cDUS64iWbHtSM1TsJteBS0A==", "license": "MIT", "dependencies": { "@azure/core-auth": "^1.9.0", @@ -2305,9 +2305,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -2827,9 +2827,9 @@ } }, "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -3506,9 +3506,9 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.7.tgz", + "integrity": "sha512-FjiwU9HaHW6YB3H4a1sFudnv93lvydNjz2lmyUXR6IwKhGI+bgL3SOZrBGn6kvvX2pJvhEkGSGjyTHN47O4rqA==", "dev": true, "license": "ISC", "dependencies": { @@ -4237,9 +4237,9 @@ } }, "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "dev": true, "license": "MIT" }, @@ -4414,9 +4414,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.3.tgz", + "integrity": "sha512-M2GCs7Vk83NxkUyQV1bkABc4yxgz9kILhHImZiBPAZ9ybuvCb0/H7lEl5XvIg3g+9d4eNotkZA5IWwYl0tibaA==", "dev": true, "license": "ISC", "dependencies": { @@ -4485,9 +4485,9 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.7.tgz", + "integrity": "sha512-FjiwU9HaHW6YB3H4a1sFudnv93lvydNjz2lmyUXR6IwKhGI+bgL3SOZrBGn6kvvX2pJvhEkGSGjyTHN47O4rqA==", "dev": true, "license": "ISC", "dependencies": { @@ -5604,9 +5604,9 @@ } }, "node_modules/sinon/node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { diff --git a/package.json b/package.json index 3e647400..dccb851e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "author": "Microsoft Application Insights Team", "license": "MIT", "bugs": "https://github.com/microsoft/ApplicationInsights-node.js/issues", - "version": "3.13.0", + "version": "3.14.0", "description": "Microsoft Application Insights module for Node.js", "repository": { "type": "git", @@ -68,8 +68,8 @@ "@azure/functions": "^4.11.2", "@azure/functions-old": "npm:@azure/functions@3.5.1", "@azure/identity": "^4.6.0", - "@azure/monitor-opentelemetry": "^1.15.1", - "@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.38", + "@azure/monitor-opentelemetry": "^1.16.0", + "@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.39", "@azure/opentelemetry-instrumentation-azure-sdk": "^1.0.0-beta.7", "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.208.0", diff --git a/src/types.ts b/src/types.ts index 70918dcd..71ff523c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,7 +10,7 @@ import { MetricReader } from "@opentelemetry/sdk-metrics"; import { OTLPExporterNodeConfigBase } from "@opentelemetry/otlp-exporter-base"; -export const APPLICATION_INSIGHTS_OPENTELEMETRY_VERSION = "3.13.0"; +export const APPLICATION_INSIGHTS_OPENTELEMETRY_VERSION = "3.14.0"; export const DEFAULT_ROLE_NAME = "Web"; export const AZURE_MONITOR_STATSBEAT_FEATURES = "AZURE_MONITOR_STATSBEAT_FEATURES"; diff --git a/test/functionalTests/runner/ingestion.js b/test/functionalTests/runner/ingestion.js index ae0536c3..f389b382 100644 --- a/test/functionalTests/runner/ingestion.js +++ b/test/functionalTests/runner/ingestion.js @@ -37,15 +37,19 @@ class Ingestion { .on('error', () => null) .on('end', (d) => { data += (d || ""); - let items = data.split("\n"); + let items = data.split("\n").filter(item => item.trim() !== ""); items.forEach(function (item) { - item = JSON.parse(item); - if (!Array.isArray(item)) { - item = [item]; + try { + item = JSON.parse(item); + if (!Array.isArray(item)) { + item = [item]; + } + item.forEach((subItem) => { + self.processItem(subItem); + }); + } catch (e) { + console.warn("INGESTION: Failed to parse item:", e.message); } - item.forEach((subItem) => { - self.processItem(subItem); - }); }, self); response.end(JSON.stringify({ itemsRecieved: items.length, diff --git a/test/functionalTests/testApp/main.js b/test/functionalTests/testApp/main.js index 2c60c608..cf732e56 100644 --- a/test/functionalTests/testApp/main.js +++ b/test/functionalTests/testApp/main.js @@ -9,6 +9,7 @@ if (testconfig.AppInsightsEnabled) { connectionString:`InstrumentationKey=${testconfig.InstrumentationKey};IngestionEndpoint=${testconfig.EndpointBaseAddress}` }, samplingRatio: parseFloat(testconfig.SampleRate), + tracesPerSecond: 0, // Disable rate limiting so all test traces are captured instrumentationOptions: { azureSdk: { enabled: true diff --git a/test/unitTests/shim/telemetryClient.tests.ts b/test/unitTests/shim/telemetryClient.tests.ts index 33d72c81..84a812af 100644 --- a/test/unitTests/shim/telemetryClient.tests.ts +++ b/test/unitTests/shim/telemetryClient.tests.ts @@ -169,6 +169,12 @@ describe("shim/TelemetryClient", () => { }); describe("#manual track APIs", () => { + // Allow rate limiter to recover between tests so each span-creating test + // gets a fresh budget from the default RateLimitedSampler (5 traces/sec) + beforeEach(async () => { + await new Promise(resolve => setTimeout(resolve, 250)); + }); + it("trackDependency http", async () => { const telemetry: DependencyTelemetry = { name: "TestName", @@ -565,6 +571,35 @@ describe("shim/TelemetryClient", () => { }); }); + describe("#rate limiting behavior", () => { + it("should rate limit spans when creating many rapidly", async () => { + // Wait for rate limiter to fully recover + await new Promise(resolve => setTimeout(resolve, 500)); + testProcessor.spansProcessed = []; + + const totalSpans = 20; + // Create many spans as fast as possible (far exceeding 5/sec default) + for (let i = 0; i < totalSpans; i++) { + client.trackDependency({ + name: `RateLimitTest-${i}`, + duration: 100, + resultCode: "200", + data: "http://test.com", + dependencyTypeName: "HTTP", + success: true, + }); + } + await tracerProvider.forceFlush(); + const sampledCount = testProcessor.spansProcessed.length; + + // Rate limiter should allow some but not all spans through + assert.ok(sampledCount >= 1, + `Expected at least 1 span to be sampled, got ${sampledCount}`); + assert.ok(sampledCount < totalSpans, + `Expected rate limiting to drop some spans when creating ${totalSpans} rapidly, but all ${sampledCount} were sampled`); + }); + }); + describe("initialization modes", () => { it("does not call useAzureMonitor for isolated clients", async () => { const useAzureMonitorStub = sandbox.stub(main, "useAzureMonitor");