How to Monitor Your Alexa Skill
In this post, I present a solution for monitoring your Alexa Skills through software debugging and use of AWS Lambda.
Join the DZone community and get the full member experience.Join For Free
Software debugging is an essential capability for developers, but debugging serverless architectures requires a dedicated approach. The backend of an Alexa Skill is in most cases serverless functions, using, for example, AWS Lambda. Debugging, monitoring and testing are the top challenges when it comes to serverless, with debugging being the most common challenge.
Serverless functions are, by design, very hard to attach anything to. As a result, we’re witnessing new solutions for debugging serverless, both locally and remotely. In this post, I present a solution for monitoring your Alexa Skills.
Our Skill Backend by nature is event-driven. This makes debugging harder as minor differences in the event content, format or order can make big differences. Simulating those events is potentially a big difference that can make it harder to reproduce and test.
When facing a bug in a Skill, reproducing it reliably can be half the battle. In many data-driven environments, the main factor in actually reproducing the bug is getting the right input data. Migrating data from production to development can easily take hours (or even days) and can be hampered by security, compliance and other considerations. Production debugging tools allow developers to study the bug ‘in the wild’ in production without wasting time and resources on data migration, and without exposing sensitive data.
There are a lot of tools that help us to debug and monitor serverless applications. Making a previous study looking for which one will be better to monitor an Alexa Skill, I've chosen Sentry
Let's go deeper!
Sentry is an open-source company, providing an application monitoring platform that helps you identify issues in real-time. Sentry fundamentally is a service that helps you monitor and fix crashes in real-time. The server is in Python, but it contains a full API for sending events from any language, in any application. We are going to focus on Sentry concepts of Context, breadcrumbs, and environments to make proper monitoring of our skills.
Sentry supports additional context with events. Often this context is shared among any event captured in its lifecycle, and includes the following components:
Which contexts are we going to use? these:
- User: the user of the Alexa requests
- Tags: it allows us to classify and contextualize every request to monitor and track all requests well. We will set up these tags:
- request_id: the id of the request received.
- application_id: the id of our skill. It allows us to make a quick search to check all the requests of one skill.
- session_id: the id of the session of one user using one skill. It will help us to track a single session of one user.
- person_id: with personalization, your skill can distinguish between individual speakers in the account. So if Alexa recognize the current voice we will receive the
Personobjects which include the
With environments, we can filter events depending on the environment of execution i.e dev/prod and depending as well of the release of our skill backend. You can filter releases by which environment they’ve been deployed to. For example, a release linked to a QA deploy and a Prod deploy will appear in your view when filtering by QA as well as Prod.
Sentry supports a concept called Breadcrumbs, which is a trail of events that happened before an issue. Often these events are very similar to traditional logs, but also have the ability to record more rich structured data. In these breadcrumbs, we will put relevant data of our Alexa Skill such as requests (contexts, session), responses, the overall time of execution, etc.
I am not going to start from scratch in this post. I will reuse the project I have used in my post-Alexa Skill, AWS CloudFormation y Serverless Application Model (SAM).
First of all, what we have to add is the Sentry dependency in the
After that, we need to initialize the Sentry client. I initialize it at the same time the lambda is called with the method
Sentry.inti() is called it will read the
sentry.properties resource file which has the following properties:
- dsn: the unique URL of your Sentry project. You can get it online in your Sentry project. For example ttp://email@example.com/asdfas
- release: to make better monitoring of our skill, it is good to have this property set to filter when something happens.
- environment: it is also important to set because of knowing the current environment of execution. E.g.: dev, prod.
- stacktrace.app.packages: the java package you want to monitor. In our case
After adding the dependency, now we are going to focus on our two interceptors.
LogResponseInterceptor. Why those two?
LogRequestInterceptorwe have the request received which have all the information we need to create our Sentry User and Sentry tags to monitor the current request:
LogResponseInterceptor we have here the response we are going to send and we can calculate the time in milliseconds od the current execution. As these are the last lines of our skill during the execution, one of the main tasks of this interceptor is to send all the Sentry event to the cloud with the method
Sentry.capture(). Finally, we clean everything with
Sentry.clearContext() for future Alexa requests:
Logging in Our Skill With Sentry
One of the most important tasks in a serverless architecture is the log. It is essential to know what had happened during an execution. In this example, we will use an auxiliary Class called
LogUtilities which have only one method
log(String toLog) this method has two tasks:
- Log using log$j2 or lambda4j libraries to have structured log files.
- Create a Sentry breadcrumb that will be added to the rest of the breadcrumbs and will be available in our Sentry console as part of the event generated by the request. It will help us to track what has happened in a request.
So with this class, you can call it wherever you want to lag and add your breadcrumbs. It will help you to monitor and have good tracking of your skills.
The last but not the least, when we are talking about monitoring, are exceptions.
In our Alexa Skill, we have one place to catch all the Exceptions. This
MyExceptionHandler is our exception handler. When we have an exception, the
LogResponseInterceptor is not going to be executed. This is why here we capture the exception with Sentry and we clean its context as well:
The Power of Sentry
Now we have set our Skill with Sentry. Let's send an Alexa request to its backend to see what happened and then we will check the Sentry console:
WOW! We have a new entry!
Now click on the item and let's see what is inside:
Here you have the information about the event: time of the Alexa request was sent and all the tags. Every Tag is clickable to filter depending on your needs.
If we scroll down, we will see the breadcrumbs. It means a quick view of what happened during that Alexa request:
NOTE: The data of the request and response have been removed for this example.
And then if we continue scrolling down we will see the User (Alexa username and Alexa device) information and the information about the Sentry SDK used.
If we have an exception, we can see in Sentry Dashboard as well:
We can also see all the execution information clicking on the event:
You can see the full stacktrace clicking on the Raw button:
Before concluding this topic, I would like to add that with Sentry you can make searches of any tag, user, environment, release you have.
- Give me all the Alexa requests that came from one user and one skill:
- request_id:amzn1.echo-API.request.[unique-value-here] application_id:amzn1.ask.skill.[unique-value-here]
- Give me all the Alexa requests that came from one session:
- Give me all the Alexa requests that came from the current release:
- release: XXX
You can save these searches as quick ones and it will be available in one click.
With the help of Sentry, we quickly went from having zero knowledge to understanding the error. Using the right tools at the right time can help tremendously with these kinds of issues.
I've made this example in Java but you can use it in other languages that Alexa supports because Sentry is available in a lot of programming languages such as NodeJS, Python, Java, Kotlin, C#, PHP, Ruby, Go, iOS Android, etc.
You can take a look at all the Sentry documentation here.
Regarding the pricing, Sentry has a development plan that comes with 5.000 events per month. In our case, 5.000 Alexa requests from our Skill. You can see plans here.
That’s all, folks! You can find all the code in my GitHub.
I hope it will be useful! If you have any doubts or questions do not hesitate to contact me or put a comment below!
Opinions expressed by DZone contributors are their own.