Recently, I've integrated Crave Engine with application insights to monitor on all the chat channels. But the most difficult was implementing it for my Alexa Skill. We need to take care of timeout, callbacks and flushing data as soon as possible.

Azure Application Insights monitors your back-end services and components after you deploy them to help you discover and rapidly diagnose performance and other issues.

Usually, App Insights will send all the data in batches asynchronously(or in the background). This way, it will make use of resources efficiently. But, for Alexa skills running on AWS Lambda, the code is executed only when it will trigger, and as soon as the code execution finishes, it stops after some time. But App Insights usually waits > 15 seconds before sending the data. This scenario will cause Alexa Skill to timeout, or Lambda function will fail to execute due to function time-out.

First, you'll need to install applicationinsights node package. This command will install the package and add to your package.json file.

npm i --save applicationinsights

Next, include this package at the top of your lambda function:

let appInsights = require('applicationinsights');
appInsights.setup(process.env.COMMON_APP_INSIGHTS_INSTRUMENTATION_KEY).start();
let appInsightsClient = appInsights.defaultClient;

// Then to track something, use this anywhere in code
appInsightsClient.trackEvent({name: "NAME_HERE", properties: "PROPS_HERE"});

Now, when you invoke your Alexa Skill, You'll find that your skill is failing and nothing returns. This failing is because Alexa is waiting for the app insights to complete the request and since the default value is to send insights is every 15 seconds, Alexa skill is timed-out.

To Prevent this, we need to use flush() method provided by App Insights package which will flush data immediately to the server. Also, you need to change maxBatchIntervalMs and setUseDiskRetryCaching(false). You can do this by changing your code to:

let appInsights = require('applicationinsights');
appInsights.setup(process.env.COMMON_APP_INSIGHTS_INSTRUMENTATION_KEY)
    .setUseDiskRetryCaching(false).start();

let appInsightsClient = appInsights.defaultClient;

appInsightsClient.config.maxBatchIntervalMs = 0;

....
....

appInsightsClient.flush();

Finally, below is the typical sketch of lambda function which integrates Application Insights:

// App Insights
let appInsights = require('applicationinsights');
appInsights.setup(process.env.COMMON_APP_INSIGHTS_INSTRUMENTATION_KEY).setUseDiskRetryCaching(false).start();
let appInsightsClient = appInsights.defaultClient;
appInsightsClient.config.maxBatchIntervalMs = 0;

const Alexa = require('ask-sdk-core');

const LaunchRequestHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
  },
  handle(handlerInput) {
    appInsightsClient.trackEvent({name: "NAME_HERE", properties: "PROPS_HERE"});
    
    const speechText = `Hi, Welcome to my app.`;
    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(speechText)
      .withSimpleCard('Welcome', speechText)
      .getResponse();
  },
};


const HelpIntentHandler = {
  canHandle(handlerInput) {
    ...
  },
  handle(handlerInput) {
    ...
  },
};


const CancelAndStopIntentHandler = {
  canHandle(handlerInput) {
    ...
  },
  handle(handlerInput) {
    ...
  },
};


const SessionEndedRequestHandler = {
  canHandle(handlerInput) {
    ...
  },
  handle(handlerInput) {
    ...
  },
};


const ErrorHandler = {
  canHandle() {
    ...
  },
  handle(handlerInput, error) {
    ...
  },
};

const skillBuilder = Alexa.SkillBuilders.custom();

appInsightsClient.flush();

exports.handler = skillBuilder
  .addRequestHandlers(
    LaunchRequestHandler,
    HelpIntentHandler,
    CancelAndStopIntentHandler,
    SessionEndedRequestHandler
  )
  .addErrorHandlers(ErrorHandler)
  .lambda();

You can track more custom telemetry like Metrics, Exceptions, etc. Refer to the documentation here.

Also, Take a look at: