ApplicationInsights-node.js icon indicating copy to clipboard operation
ApplicationInsights-node.js copied to clipboard

Requests Not Being Sent to Application Insights with 3.x Libraries

Open v-federicoar opened this issue 8 months ago • 11 comments

While upgrading from version 2.9.0 to 3.6.0 of the Application Insights library, we encountered an issue where requests are no longer being sent to Application Insights.

Expected Behavior: Requests should appear in Application Insights as they did with version 2.9.0.

Actual Behavior: Requests do not appear in Application Insights when using version 3.x.

The app is https://github.com/mspnp/fabrikam-dronedelivery-workload/blob/main/src/shipping/package/package.json

Runing with Node 18.9.1

the app insight initialization is https://github.com/mspnp/fabrikam-dronedelivery-workload/blob/main/src/shipping/package/app/initializer.ts

Error Logs: Running in debugger mode locally, the following error was observed (may be related to the issue):

Runing in debugger mode locally we found the error (may be related to the issue or not):
{"stack":"Error: PeriodicExportingMetricReader: metrics export failed (error undefined)\n    at PeriodicExportingMetricReader._doRun (C:\\tbd\\container-apps-fabrikam-dronedelivery\\workload\\src\\shipping\\package\\node_modules\\@opentelemetry\\sdk-metrics\\build\\src\\export\\PeriodicExportingMetricReader.js:86:19)\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at async PeriodicExportingMetricReader._runOnce (C:\\tbd\\container-apps-fabrikam-dronedelivery\\workload\\src\\shipping\\package\\node_modules\\@opentelemetry\\sdk-metrics\\build\\src\\export\\PeriodicExportingMetricReader.js:54:13)","message":"PeriodicExportingMetricReader: metrics export failed (error undefined)","name":"Error"} []

Additional Information:

Main documentation: Azure Monitor Application Insights for Node.js Library: Application Insights on npm

Request for Assistance: I believe this issue may be related to the library itself, but I am unable to confirm. Any guidance or solutions would be greatly appreciated.

v-federicoar avatar Apr 16 '25 19:04 v-federicoar

@v-federicoar Thank you for the references. Is it only requests that you're not seeing collected, but other forms of auto-collected telemetry are?

JacksonWeber avatar Apr 17 '25 17:04 JacksonWeber

@JacksonWeber The trace shows that AzureMonitorMetricExporter sends invalid data.

node_modules\@azure\monitor-opentelemetry-exporter\dist\commonjs\export\metric.js
{"stack":"Error: PeriodicExportingMetricReader: metrics export failed (error undefined)
    at PeriodicExportingMetricReader._doRun (node_modules\\@azure\\monitor-opentelemetry\\node_modules\\@opentelemetry\\sdk-metrics\\build\\src\\export\\PeriodicExportingMetricReader.js:86:19)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async PeriodicExportingMetricReader._runOnce (node_modules\\@azure\\monitor-opentelemetry\\node_modules\\@opentelemetry\\sdk-metrics\\build\\src\\export\\PeriodicExportingMetricReader.js:54:13)",
    "message":"PeriodicExportingMetricReader: metrics export failed (error undefined)","name":"Error"} []
"{\"itemsReceived\":7,\"itemsAccepted\":6,\"appId\":null,\"errors\":[{\"index\":5,\"statusCode\":400,\"message\":\"106: Field 'value' on type 'DataPoint' is of incorrect type. Expected: double\"}]}"
{
name: "Microsoft.ApplicationInsights.Metric",
time: "2025-04-19T23:46:50.720Z",
sampleRate: 100,
instrumentationKey: "",
tags: {
    "ai.device.osVersion": "Windows_NT 10.0.20348",
    "ai.internal.sdkVersion": "fwm_node20:otel1.30.1:dst1.10.0",
    "ai.cloud.role": "unknown_service:node",
    "ai.cloud.roleInstance": "",
},
version: 1,
data: {
    baseType: "MetricData",
    baseData: {
    metrics: [
        {
        name: "Process_Time_Normalized",
        value: NaN,
        dataPointType: "Aggregation",
        count: 1,
        },
    ],
    version: 2,
    properties: {
    },
    },
},
}

lamaks avatar Apr 19 '25 23:04 lamaks

@JacksonWeber I didn't notice any other auto-collected telemetry (to be honest, I didn't pay much attention to the others). However, I created an ad-hoc trace and was able to see my trace.

v-federicoar avatar Apr 21 '25 13:04 v-federicoar

@lamaks This is a known issue in 1.10.0 of the @azure/monitor-opentelemetry package. Please ensure that your version of @azure/monitor-opentelemetry is at 1.9.0. There's an updated version of the applicationinsights package with the fixes for this with a release coming through now.

JacksonWeber avatar Apr 21 '25 18:04 JacksonWeber

@JacksonWeber Thank you for the prompt fix. The @azure/monitor-opentelemetry version 1.11.0 has this issue fixed.

lamaks avatar Apr 22 '25 01:04 lamaks

After testing version 3.7.0, the error is no longer present. However, the request information is still not appearing in the Azure Portal Application Insights logs (request table).
The ad-hoc trace is visible in the "trace table".
I have no idea why this is happening.

v-federicoar avatar Apr 28 '25 15:04 v-federicoar

I also have this setup on an app service running in iisexpress, and there is no data being logged to Application Insights.

joshvito avatar Jun 03 '25 17:06 joshvito

@joshvito can you provide more details on exactly what your setup looks like?

JacksonWeber avatar Jun 09 '25 20:06 JacksonWeber

@JacksonWeber Sure! The Azure we have an Application Insights instance, and a windows flavor of an App Service. Both in the same Subscription and Location.

Configuration on the app service includes the following:

  • Environment Variables Image Image

Software

There is a root web.config on the app service:

// web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.webServer>
        <webSocket enabled="false" />
        <handlers>
            <add name="iisnode" path="main.js" verb="*" modules="iisnode" />
        </handlers>
        <rewrite>
            <rules>
                <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
                    <match url="^main.js\/debug[\/]?" />
                </rule>
                <rule name="StaticContent">
                    <action type="Rewrite" url="public{REQUEST_URI}" />
                </rule>
                <rule name="DynamicContent">
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True" />
                    </conditions>
                    <action type="Rewrite" url="main.js" />
                </rule>
            </rules>
        </rewrite>
        <security>
            <requestFiltering>
                <hiddenSegments>
                    <remove segment="bin" />
                </hiddenSegments>
            </requestFiltering>
        </security>
        <httpErrors existingResponse="PassThrough" />
    </system.webServer>
</configuration>

Main.js is a NestJs server of the express variety. Here is how we initialize Application Insights at startup.

// main.ts
import { environment } from './environments/environment'
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import { normalizePort } from './common/utility';
import * as applicationinsights from 'applicationinsights'; // semver version ^2.9.6 

async function bootstrap() {
  process.env = {...process.env, ...environment};
// tried "const appInsights = applicationinsights.setup();" But it throws in version 2;
  const appInsights = applicationinsights.setup(process.env.APPLICATION_INSIGHTS_INSTRUMENTATION_KEY || process.env.APPINSIGHTS_INSTRUMENTATIONKEY);
  appInsights
    .setAutoCollectRequests(true)
    .setAutoCollectPerformance(true, true)
    .setAutoCollectExceptions(true)
    .setAutoCollectDependencies(true)
    .setAutoCollectConsole(true, false)
    .setAutoCollectPreAggregatedMetrics(true)
    .setSendLiveMetrics(true)
    .setInternalLogging(true, true)
    .enableWebInstrumentation(true)
    .start();
  
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  const globalPrefix = 'some-prefix';
  const host = process.env.HOST || 'localhost';
  const port = process.env.PORT || '3000';

  app.setGlobalPrefix(globalPrefix);  
  await app.listen(normalizePort(port), host);

  Logger.log(`🚀 Application is running on: http://${host}:${port}/${globalPrefix}`);
}

bootstrap();

Notes on what I tried.

I tried version 3.7.0 and 3.5.0 before reverting to latest major version 2.

What did i notice?

  • When using the major version 3.x above, the App Service was getting traffic and showing requests, but nothing was being logged in Application Insights. Once I downgraded to major version 2, everything just works.

20250611 Try Workaround EDITS

I tried the work around from #1354, but it still had issues. Maybe I misread the workaround. So, the files were changed to:

// main.ts
import { environment } from './environments/environment'
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { NestExpressApplication } from '@nestjs/platform-express';
import { normalizePort } from './common/utility';
import  './telemetry.cjs';

async function bootstrap() {
  process.env = {...process.env, ...environment};
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  const globalPrefix = 'api/comp-points';
  const host = process.env.HOST || 'localhost';
  const port = process.env.PORT || '3000';

  app.enableCors();
  app.set('trust proxy', true);
  app.setGlobalPrefix(globalPrefix);
  
  await app.listen(normalizePort(port), host);

  Logger.log(`🚀 Application is running on: http://${host}:${port}/${globalPrefix}`);
}

bootstrap();

Added a telemetry.cjs file

// telemetry.cjs
const applicationinsights = require('applicationinsights');
const appInsights = applicationinsights.setup();
  appInsights
    .setAutoCollectRequests(true)
    .setAutoCollectPerformance(true, true)
    .setAutoCollectExceptions(true)
    .setAutoCollectDependencies(true)
    .setAutoCollectConsole(true, false)
    .setAutoCollectPreAggregatedMetrics(true)
    .setSendLiveMetrics(true)
    .start();

module.exports = {
  telemetryClient: applicationinsights.defaultClient
}

The application started as expected, but none of requests were logged.

Here we can see only the deploy slot (which contains old code w/ v2.9.6) requests are being logged (healthchecks); Image

Yet I sent a bunch of requests. Image

joshvito avatar Jun 10 '25 14:06 joshvito

@joshvito this looks like an issue with OpenTelemetry's ESM compatibility given that you're not seeing any telemetry at all and downgrading to 2.x solves the issue - can you refer to https://github.com/microsoft/ApplicationInsights-node.js/issues/1354 and see if following the workaround for using OTel with ESM works for you?

JacksonWeber avatar Jun 10 '25 23:06 JacksonWeber

Using the workaround from #1354 , the requests are not being logged. Maybe my implementation has an error? I updated my comment above to include the workaround attempt.

joshvito avatar Jun 11 '25 20:06 joshvito