Troubleshoot an Echo Button Skill

If your skill code is in AWS Lambda, you can add logging to your code to help you troubleshoot issues. The logs go to Amazon CloudWatch, which is an AWS service that monitors AWS resources and applications in real time. This topic describes how to add logging to your skill code and how to access the logs in CloudWatch.

How Logging Works

Each time your Lambda function executes, AWS Lambda automatically sends information to CloudWatch on your behalf. By default, this logging is minimal and does not contain the content of the requests and responses that your skill exchanges with Alexa. You can add more detailed logging by inserting logging code into your skill as described later in this topic.

AWS Lambda writes log entries to CloudWatch in a log group called /aws/lambda/<function-name>. If you are on the detail page of your function in the AWS Lambda console, you can access the CloudWatch logs by selecting the Monitoring tab and then selecting Jump to Logs at the top right of any of the CloudWatch metric graphs. All of the Jump to Logs links take you to the same place.

View Logs in CloudWatch

Adding Logging to Your Skill Code

To add logging to your skill code, use the logging syntax described in the following CloudWatch documentation:

This section shows how to log requests and responses in Node.js. An example of a request that Alexa sends to your skill is a GameEngine.InputHandlerEvent that reports that an Echo Button was pressed. Examples of responses that your skill sends to Alexa are a GameEngine.StartInputHandler directive to set up the Game Engine, and a GadgetController.SetLight directive to control Echo Buttons lights.

If your skill is having problems, examining the CloudWatch logs of requests and responses is a good place to start.

  • Requests from Alexa – To capture the JSON representation of the requests that Alexa sends your skill, put this line anywhere within the exports.handler function of your skill's index.js file:
    console.log("===REQUEST=== \n" + JSON.stringify(event));
    

    The following example shows the line in context:

    exports.handler = function (event, context) {
      console.log("===REQUEST=== \n" + JSON.stringify(event));  
      const alexa = Alexa.handler(event, context);
      alexa.APP_ID = APP_ID;
      alexa.registerHandlers(handlers);
      alexa.execute();
    };
    

    You don't need to precede the line with ===REQUEST===, but including distinctive text makes it easier to scan a list of logs.

  • Responses to Alexa – To log the JSON representation of the response that your skill sends to Alexa, put the logging code immediately before you send the response. Add the following line immediately before each call to this.emit:
    console.log("===RESPONSE=== "+ JSON.stringify(this.handler.response));
    

    The following is an example of where you might add the line:

    'LaunchRequest': function () {
      console.log("===RESPONSE=== "+ JSON.stringify(this.handler.response));
      this.emit('MyLaunchFunction');
    },
    

    Again, you don't need to precede the line with ===RESPONSE===. This can be anything that helps you find the logs.

Viewing the Logs

To view the CloudWatch logs for your skill, do the following:

  1. If you haven't already, add logging to your skill code as described previously.
  2. Run your skill at least once. For information about how to run your skill on a real device, see End-to-End Testing.
  3. Sign in to the AWS Management Console and navigate to the AWS Lambda console, which is located under Compute services.
  4. In the function list, select the function that contains your skill code. If you can't find your function, look at the region selector at the top right of the page to ensure that you are in the same AWS region as your skill code.
  5. On the detail page of your function, select the Monitoring tab.
  6. At the top right of any of the CloudWatch metric graphs, select Jump to Logs.
  7. In the Filter events field, enter something to find within the logs. Examples are distinctive words that you used in your log text (such as ===RESPONSE===), a directive name, error, and so on. The Filter events field is case sensitive.
  8. In the results, expand individual rows to examine the logs.

Example 1: Using CloudWatch Logs to Display Directives

Suppose that, when you run your Echo Button skill, the skill doesn't respond to Echo Button presses. You want to verify that the directive that you used to set up the Game Engine, GameEngine.StartInputHandler, looks correct. You could follow these debugging steps:

  1. If you haven't already, add logging to your skill code as described previously.
  2. Run your skill.
  3. In the AWS Lambda console, select the function that contains your skill code.
  4. Select the Monitoring tab and then select Jump to Logs at the top right of any of the CloudWatch metric graphs.
  5. In the Filter events field, enter StartInputHandler. Be sure to type it exactly as shown, because the Filter events field is case sensitive.
  6. Expand individual rows to examine the logs. In this case, for example, you might see that for action, you specified dpwn instead of down:
    2017-11-27T18:43:14.111Z d2d18ad0-d3a2-11e7-8213-85503f9781e6 ===RESPONSE===
    {
        "version": "1.0",
        "response": {
            "directives": [
               {
                    "type": "GameEngine.StartInputHandler",
                    "timeout": 30000,
                    "recognizers": {
                        "button_down_recognizer": {
                            "type": "match",
                            "fuzzy": false,
                            "anchor": "end",
                            "pattern": [
                                {
                                    "action": "dpwn"
                                }
                            ]
                         },
             ...
    

Example 2: Using CloudWatch Logs to Find Errors

Suppose that you run your Echo Button skill and Alexa says "There was a problem with the requested skill's response." You could follow these debugging steps:

  1. If you haven't already, add logging to your skill code as described previously.
  2. Run your skill.
  3. In the AWS Lambda console, select the function that contains your skill code.
  4. Select the Monitoring tab and then select Jump to Logs at the top right of any of the CloudWatch metric graphs.
  5. In the Filter events field, enter error. Be sure to type it exactly as shown, because the Filter events field is case sensitive.
  6. Expand individual rows to examine the logs. For example, you might see the following, which gives you a clue to look at your buildMyAnimation function:
    module initialization error: ReferenceError at buildMyAnimation (/var/task/index.js:276:49) ...
    

Example 3: Using Alexa Skill Cards to Find Errors

There are some errors for which Alexa automatically publishes a skill card to your home page. For more information, see Amazon Alexa App Home Page Cards. The skill card provides the request ID and some information about the error. You can use the request ID to look up the CloudWatch log to see if the log contains additional information about the error.

For example, suppose that you run your Echo Button skill and Alexa says "There was a problem with the requested skill's response." You could follow these debugging steps:

  1. If you haven't already, add logging to your skill code as described previously.
  2. Run your skill.
  3. Log in to the Amazon Alexa app (alexa.amazon.com) and look at the home page.
  4. If you see a skill card that reports an error, take note of the request identifier that the card displays.
    Error Shown in Skill Card
  5. In the AWS Lambda console, select the function that contains your skill code.
  6. Select the Monitoring tab and then select Jump to Logs at the top right of any of the CloudWatch metric graphs.
  7. In the Filter events field, enter error, then a space, and then the first several alphanumeric characters of the request ID that follows amzn1.echo-api.request. Continuing the previous example, you might enter abcd0123.
  8. In the results, expand individual rows to examine the logs. In this case, the information about the error is in the SessionEndedRequest:
    "request": {
     "type": "SessionEndedRequest",
     "requestId": "amzn1.echo-api.request.abcd0123-4567-89ab-012345678910",
     "timestamp": "2017-12-08T18:51:07Z",
     "locale": "en-US",
     "reason": "ERROR",
     "error": {
         "type": "INVALID_RESPONSE",
         "message": "Invalid SSML Output Speech for requestId amzn1.echo-api.request.abcd0123-4567-89ab-012345678910. Error: Fatal error occurred when processing SSML content. This usually happens when the SSML is not well formed. Error: Unexpected character ' ' (code 32) (missing name?)\n at [row,col {unknown-source}]: [1,26]"
     }
    }
    

Problems Viewing the Logs

If you don't see any log data in CloudWatch or you get a "There was an error loading Log Streams" error when you try to access your logs, CloudWatch logging might not be properly set up for your Lambda function. The log stream error can happen, for example, if your Lambda function uses a role that you created for another skill that you have since deleted. Another problem might be that your role does not contain permissions to write to CloudWatch.

The easiest way to solve this problem is to create a new role as follows:

  1. In the AWS Lambda console, select the function that contains your skill code.
  2. Ensure that you are on the Configuration tab.
  3. Scroll down past the code. Under Execution role, instead of Choose an existing role, select Create new role from template(s).
  4. Under Role name, enter a name for the role.
  5. Under Policy templates, select Simple Microservice permissions.
  6. At the top of the page, select Save.
  7. Run your skill again.
  8. In the AWS Lambda console, on the function's detail page, select the Monitoring tab and then select Jump to Logs at the top right of any of the CloudWatch metric graphs. The logs should be accessible now.