Repository: microsoft/ApplicationInsights-node.js
Pull request #1435 (2025-06-19 03:23:24)

Fix Preserving Custom Values Passed to Track Methods
Fixes https://github.com/microsoft/ApplicationInsights-node.js/issues/1432


Patch:
diff --git a/src/shim/telemetryClient.ts b/src/shim/telemetryClient.ts
index 289124c..10e09a5 100644
--- a/src/shim/telemetryClient.ts
+++ b/src/shim/telemetryClient.ts
@@ -172,9 +172,16 @@ export class TelemetryClient {
         const attributes: Attributes = {
             ...telemetry.properties,
         };
-        attributes[SEMATTRS_HTTP_METHOD] = "HTTP";
-        attributes[SEMATTRS_HTTP_URL] = telemetry.url;
-        attributes[SEMATTRS_HTTP_STATUS_CODE] = telemetry.resultCode;
+        // Only set HTTP attributes if we have the relevant data
+        if (!telemetry.name) {
+            attributes[SEMATTRS_HTTP_METHOD] = "HTTP";
+        }
+        if (telemetry.url) {
+            attributes[SEMATTRS_HTTP_URL] = telemetry.url;
+        }
+        if (telemetry.resultCode) {
+            attributes[SEMATTRS_HTTP_STATUS_CODE] = telemetry.resultCode;
+        }
         const options: SpanOptions = {
             kind: SpanKind.SERVER,
             attributes: attributes,
@@ -182,6 +189,17 @@ export class TelemetryClient {
         };
         const span: any = trace.getTracer("ApplicationInsightsTracer")
             .startSpan(telemetry.name, options, ctx);
+            
+        if (telemetry.id) {
+            try {
+                if (span._spanContext) {
+                    span._spanContext.traceId = telemetry.id;                
+                }
+            } catch (error) {
+                diag.warn('Unable to set custom traceId on span:', error);
+            }
+        }
+        
         span.setStatus({
             code: telemetry.success ? SpanStatusCode.OK : SpanStatusCode.ERROR,
         });
@@ -219,9 +237,13 @@ export class TelemetryClient {
         };
         if (telemetry.dependencyTypeName) {
             if (telemetry.dependencyTypeName.toLowerCase().indexOf("http") > -1) {
-                attributes[SEMATTRS_HTTP_METHOD] = "HTTP";
-                attributes[SEMATTRS_HTTP_URL] = telemetry.data;
-                attributes[SEMATTRS_HTTP_STATUS_CODE] = telemetry.resultCode;
+                // Only set HTTP URL and status code for HTTP dependencies
+                if (telemetry.data) {
+                    attributes[SEMATTRS_HTTP_URL] = telemetry.data;
+                }
+                if (telemetry.resultCode) {
+                    attributes[SEMATTRS_HTTP_STATUS_CODE] = telemetry.resultCode;
+                }
             } else if (Util.getInstance().isDbDependency(telemetry.dependencyTypeName)) {
                 attributes[SEMATTRS_DB_SYSTEM] = telemetry.dependencyTypeName;
                 attributes[SEMATTRS_DB_STATEMENT] = telemetry.data;
@@ -241,6 +263,17 @@ export class TelemetryClient {
         };
         const span: any = trace.getTracer("ApplicationInsightsTracer")
             .startSpan(telemetry.name, options, ctx);
+            
+        if (telemetry.id) {
+            try {
+                if (span._spanContext) {
+                    span._spanContext.traceId = telemetry.id;
+                }
+            } catch (error) {
+                diag.warn('Unable to set custom traceId on span:', error);
+            }
+        }
+        
         span.setStatus({
             code: telemetry.success ? SpanStatusCode.OK : SpanStatusCode.ERROR,
         });


Test patch:
diff --git a/test/unitTests/shim/telemetryClient.tests.ts b/test/unitTests/shim/telemetryClient.tests.ts
index c12486b..84042bb 100644
--- a/test/unitTests/shim/telemetryClient.tests.ts
+++ b/test/unitTests/shim/telemetryClient.tests.ts
@@ -256,11 +256,50 @@ describe("shim/TelemetryClient", () => {
             assert.equal(spans[0].name, "TestName");
             assert.equal(spans[0].endTime[0] - spans[0].startTime[0], 2); // hrTime UNIX Epoch time in seconds
             assert.equal(spans[0].kind, 1, "Span Kind"); // Incoming
-            assert.equal(spans[0].attributes["http.method"], "HTTP");
             assert.equal(spans[0].attributes["http.status_code"], "401");
             assert.equal(spans[0].attributes["http.url"], "http://test.com");
         });
 
+        it("trackRequest with custom id sets traceId", async () => {
+            const customId = "custom-trace-id-123456789abcdef0";
+            const telemetry: RequestTelemetry = {
+                id: customId,
+                name: "CustomTraceRequest",
+                duration: 1000,
+                resultCode: "200",
+                url: "http://example.com",
+                success: true,
+            };
+            client.trackRequest(telemetry);
+            await tracerProvider.forceFlush();
+            const spans = testProcessor.spansProcessed;
+            assert.equal(spans.length, 1);
+            assert.equal(spans[0].name, "CustomTraceRequest");
+            // Verify that the span's traceId matches the custom id provided
+            assert.equal(spans[0].spanContext().traceId, customId);
+        });
+
+        it("trackDependency with custom id sets traceId", async () => {
+            const customId = "custom-dependency-trace-id-abcdef";
+            const telemetry: DependencyTelemetry = {
+                id: customId,
+                name: "CustomTraceDependency",
+                duration: 500,
+                resultCode: "200",
+                data: "http://api.example.com",
+                dependencyTypeName: "HTTP",
+                target: "api.example.com",
+                success: true,
+            };
+            client.trackDependency(telemetry);
+            await tracerProvider.forceFlush();
+            const spans = testProcessor.spansProcessed;
+            assert.equal(spans.length, 1);
+            assert.equal(spans[0].name, "CustomTraceDependency");
+            // Verify that the span's traceId matches the custom id provided
+            assert.equal(spans[0].spanContext().traceId, customId);
+        });
+
         it("trackMetric", async () => {
             const telemetry = {
                 name: "TestName",