3
votes

I'm trying to log Application Insights metrics from AWS Lambda written in node.js. Here is my code:

const appInsights = require("applicationinsights");
appInsights.setup("<guid>");

module.exports.monitor = (event, context, callback) => {
  let client = appInsights.defaultClient;
  // context.callbackWaitsForEmptyEventLoop = false;

  client.trackMetric({name: "AI Test", value: 25}); 

  const response = { statusCode: 200, body: 'done' };
  callback(null, response);
};

The problem is that Lambda calls time out.

If I uncomment context.callbackWaitsForEmptyEventLoop = false; statement, the timeouts are gone and AWS works. But I only receive one metric value in Application Insights: from the very first call. Subsequent calls don't seem to come through anymore.

How can I adjust Application Insights client code to work reliably and without causing timeouts? What's going on here?

1

1 Answers

5
votes

The Application Insights SDK for Node has a default configuration that's optimized for traditional long-running server scenarios. The main one interfering in this use case is the batching and delayed sending of telemetry as the waiting for more telemetry to batch is holding the event loop open.

The easiest workaround is to flush your telemetry client:

const appInsights = require("applicationinsights");
appInsights.setup("<guid>").setUseDiskRetryCaching(false);

module.exports.monitor = (event, context, callback) => {
  let client = appInsights.defaultClient;

  client.trackMetric({name: "AI Test", value: 25}); 

  const response = { statusCode: 200, body: 'done' };
  client.flush({callback: () => {
     callback(null, response);
  }});
};

Alternatively, you could try adjusting your SDK configuration to reduce the batching interval to 0 like so: client.config.maxBatchIntervalMs = 0;

Edit: Added setUseDiskRetryCaching(false) as the disk retry feature seems to also keep the event loop open.