Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trackMetric do not works #864

Closed
russosalv opened this issue Oct 31, 2021 · 11 comments · Fixed by #887
Closed

trackMetric do not works #864

russosalv opened this issue Oct 31, 2021 · 11 comments · Fixed by #887

Comments

@russosalv
Copy link

Using application insight in Node 16 enviroment
trackMetric do not works, it's seems that data are sent ot application insight but also waiting ingestion time it do no appear on Azure

@hectorhdzg
Copy link
Member

@russosalv can you add more details about the custom metric you are sending?, you should be able to see custom metrics querying customMetrics table
image

@russosalv
Copy link
Author

russosalv commented Nov 2, 2021

hi @hectorhdzg ys sure,

i'm using nestjs framework i created a injectable that manage the application insight, then it is used in other service or controller.

Application Insight service:

import { Injectable, Scope } from '@nestjs/common';
import * as appInsights from 'applicationinsights';

@Injectable({ scope: Scope.TRANSIENT })
export class ApplicationInsightUtils {
	public telemetryClient: appInsights.TelemetryClient;
	public defaultClient: any;

	constructor() {
		let appInsights = require('applicationinsights');

		let liveMetrics = false;
		if (process.env.APPINSIGHTS_LIVEMETRICS == 'true') liveMetrics = true;

		appInsights
			.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY)
			.setAutoDependencyCorrelation(true)
			.setAutoCollectRequests(true)
			.setAutoCollectPerformance(true, true)
			.setAutoCollectExceptions(true)
			.setAutoCollectDependencies(true)
			.setAutoCollectConsole(true)
			.setUseDiskRetryCaching(true)
			.setSendLiveMetrics(liveMetrics)
			.setDistributedTracingMode(appInsights.DistributedTracingModes.AI);

		//Sampling if data are a lot
		//appInsights.defaultClient.config.samplingPercentage = 33;

		appInsights.start();

		this.telemetryClient = new appInsights.TelemetryClient();
		this.defaultClient = appInsights.defaultClient;
	}
}

and here is where used:

import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common';
import { createPrismaQueryEventHandler } from 'prisma-query-log';
import { Prisma, PrismaClient } from '@prisma/client';
import { ApplicationInsightUtils } from 'src/utils/applicationInsight.utils';
import * as appInsights from 'applicationinsights';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
	/**
	 *
	 */
	constructor(private applicationInsight: ApplicationInsightUtils) {
		super({
			log: [
				{
					level: 'query',
					emit: 'event',
				},
			],
		});
	}

	async onModuleInit() {
		await this.$connect();

		const log = createPrismaQueryEventHandler({
			format: true,
			language: 'sql',
			// linesBetweenQueries: 1
		});
		this.$on<any>('query', (event: Prisma.QueryEvent) => {
			log(event);
			console.log('Params: ', event.params);
			console.log('Duration: ' + event.duration + 'ms');
			console.log('\n');

			const stringHash = require('string-hash');
			const queryMetric = stringHash(event.query);

			// this.applicationInsight.telemetryClient.trackMetric({
			// 	name: queryMetric,
			// 	value: event.duration,
			// } as appInsights.Contracts.MetricTelemetry);

			//Seems that trtack Metric do not works with Node 16
			//WorkAround
			this.applicationInsight.telemetryClient.trackTrace({
				message: `sqlMetric: ${queryMetric}`,
				severity: appInsights.Contracts.SeverityLevel.Information,
				properties: {
					queryMetric: queryMetric,
					query: event.query,
					params: event.params,
					target: event.target,
					duration: event.duration,
					timestamp: event.timestamp,
				},
			} as appInsights.Contracts.TraceTelemetry);
		});
	}

	async enableShutdownHooks(app: INestApplication) {
		this.$on('beforeExit', async () => {
			await app.close();
		});
	}
}

as per comment in the code

  • trackTrace works great
  • trackMetric NOT

i noted also that during execution on log appear a strange error

ApplicationInsights:Sender [

  'Ingestion endpoint could not be reached. This batch of telemetry items has been lost. Use Disk Retry Caching to enable resending of failed telemetry. Error:',

  "[object Error]{ stack: 'Error: getaddrinfo ENOTFOUND dc.services.visualstudio.com\n" +

    '    at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:71:26)\n' +

    "    at GetAddrInfoReqWrap.callbackTrampoline (node:internal/async_hooks:130:17)', message: 'getaddrinfo ENOTFOUND dc.services.visualstudio.com', name: 'Error'

pls note also that application work inside a docker container, but i have same behaviour aslo running on my machine

On alpplication insight customMetrics is empty
image

@hectorhdzg
Copy link
Member

Thanks @russosalv, just one thing I noticed is that you are creating another telemetry client apart from the default one created during "setup" method, this is usually the case when people want to send to multiple Application Insights resources, you can simplify your code a little bit just using the defaultClient where all the configurations are applied, the error you are seeing in logs is because the SDK was not able to reach the ingestion endpoint and disk retry is disabled for that telemetry client, if you use the default one disk retry would be enabled and will try to send data from disk when this happens, can you provide some sample values for the name and value you are sending for the metric?, I wonder if some of these are causing conflicts for some reason.

@russosalv
Copy link
Author

Hi @hectorhdzg thx for your suggest;
are you talk about to modify code in that way?

//NOT USE THIS
this.telemetryClient = new appInsights.TelemetryClient();

//USE THIS INSTEAD
this.defaultClient = appInsights.defaultClient;

here some metric name and value that i'm sendig
query_data.csv
ng

@hectorhdzg
Copy link
Member

@russosalv yes please use only the defaultClient to avoid having multiple clients unless you really need them, following code works perfectly for me, can you try to add setInternalLogging to see if there is any warning log in the console.

    applicationinsights.setup()
    .setInternalLogging(true, true)
    .start();

applicationinsights.defaultClient.trackEvent({ name: "TestEvent" });
applicationinsights.defaultClient.trackMetric({ name: "TestMetric", value: 123 });
applicationinsights.defaultClient.trackMetric({ name: "1075945211", value: 123 });

@russosalv
Copy link
Author

Hi @hectorhdzg

i did some test with .setInternalLogging(true,true), here atached:

ApplicationInsights:Sender [
  {
    method: 'POST',
    withCredentials: false,
    headers: {
      'Content-Type': 'application/x-json-stream',
      'Content-Encoding': 'gzip',
      'Content-Length': '3974'
    }
  }
]
ApplicationInsights:Sender [
  `{"itemsReceived":23,"itemsAccepted":20,"errors":[{"index":7,"statusCode":400,"message":"106: Field 'name' on type 'DataPoint' is of incorrect type. Expected: string, Actual: 3440692220"},{"index":9,"statusCode":400,"message":"106: Field 'name' on type 'DataPoint' is of incorrect type. Expected: string, Actual: 3532534679"},{"index":21,"statusCode":400,"message":"106: Field 'name' on type 'DataPoint' is of incorrect type. Expected: string, Actual: 770300894"}]}`
]
ApplicationInsights:Sender [
  {
    method: 'POST',
    withCredentials: false,
    headers: {
      'Content-Type': 'application/x-json-stream',
      'Content-Encoding': 'gzip',
      'Content-Length': '797'
    }
  }
]
ApplicationInsights:Sender [
  `{"itemsReceived":2,"itemsAccepted":1,"errors":[{"index":0,"statusCode":400,"message":"106: Field 'name' on type 'DataPoint' is of incorrect type. Expected: string, Actual: 676514475"}]}`
]
ApplicationInsights:AzureVirtualMachine [
  Error: connect ETIMEDOUT 169.254.169.254:80
      at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1133:16)
      at TCPConnectWrap.callbackTrampoline (node:internal/async_hooks:131:17) {
    errno: -110,
    code: 'ETIMEDOUT',
    syscall: 'connect',
    address: '169.254.169.254',
    port: 80
  }
]
ApplicationInsights:Sender [
  {
    method: 'POST',
    withCredentials: false,
    headers: {
      'Content-Type': 'application/x-json-stream',
      'Content-Encoding': 'gzip',
      'Content-Length': '367'
    }
  }
]
ApplicationInsights:Sender [
  {
    method: 'POST',
    withCredentials: false,
    headers: {
      'Content-Type': 'application/x-json-stream',
      'Content-Encoding': 'gzip',
      'Content-Length': '367'
    }
  }
]
ApplicationInsights:Sender [ '{"itemsReceived":3,"itemsAccepted":3,"errors":[]}' ]
ApplicationInsights:Sender [
  {
    method: 'POST',
    withCredentials: false,
    headers: {
      'Content-Type': 'application/x-json-stream',
      'Content-Encoding': 'gzip',
      'Content-Length': '853'
    }
  }
]
ApplicationInsights:Sender [ '{"itemsReceived":8,"itemsAccepted":8,"errors":[]}' ]
ApplicationInsights:Sender [
  {
    method: 'POST',
    withCredentials: false,
    headers: {
      'Content-Type': 'application/x-json-stream',
      'Content-Encoding': 'gzip',
      'Content-Length': '637'
    }
  }
]
ApplicationInsights:Sender [ '{"itemsReceived":6,"itemsAccepted":6,"errors":[]}' ]
ApplicationInsights:Sender [
  {
    method: 'POST',
    withCredentials: false,
    headers: {
      'Content-Type': 'application/x-json-stream',
      'Content-Encoding': 'gzip',
      'Content-Length': '638'
    }
  }
]
ApplicationInsights:Sender [ '{"itemsReceived":6,"itemsAccepted":6,"errors":[]}' ]

@hectorhdzg
Copy link
Member

Thanks for the logs @russosalv, issue with your metrics is that you are sending the name as number instead of string and telemetry is being rejected on the ingestion endpoint, please convert it to string before sending and let me know how it goes.

@russosalv
Copy link
Author

Hi @hectorhdzg

i tried to chenge it but i'm still having the issue

this.applicationInsight.defaultClient.trackMetric({
    name: `sqlMetric_${queryMetric}`,
    value: event.duration,
} as appInsights.Contracts.MetricTelemetry);

@hectorhdzg
Copy link
Member

@russosalv are you getting different errors now in the logs?, the issue before was the following:
ApplicationInsights:Sender [
{"itemsReceived":2,"itemsAccepted":1,"errors":[{"index":0,"statusCode":400,"message":"106: Field 'name' on type 'DataPoint' is of incorrect type. Expected: string, Actual: 676514475"}]}
]

Please take a look to see if there is some other error coming from ingestion endpoint

@hectorhdzg
Copy link
Member

@russosalv please let me know if this is still an issue on your side

@russosalv
Copy link
Author

russosalv commented Jan 23, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants