Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Release History

### 3.13.1 ()
### 3.14.0 (2026-02-24)

#### Other Changes

Expand Down
66 changes: 33 additions & 33 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down
18 changes: 11 additions & 7 deletions test/functionalTests/runner/ingestion.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions test/functionalTests/testApp/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions test/unitTests/shim/telemetryClient.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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");
Expand Down
Loading