Improve UX by observability in front-end with Amplify and QuickSight

Example: error in console says “Find me!”
JavaScript error in console says “Find me!”

We do not know if our web application works 100% on different devices unless we observe them. I see a benefit of QuickSight to enable visualization of issues when many users face JavaScript errors and developers want to understand the issues in detail. Amplify seems to be a good starting point to enter AWS for JavaScript developers and I introduce how to quickly integrate observability into front-end development with the two services.

TL;DR

Observability in product development is to detect where and when bad user experience happens, and get an idea of what causes that helps the developer reduce time to improve. In action, there are three steps: 1) Track logs 2) Visualise traces of logs 3) Synthesis to improve by metrics. The last step classifies information into three levels: 1) Error that causes blank page 2) Warning as in hangout for more than 50ms 3) Others that you want to see. This article shows how to quickly set up a foundation of observability in the front-end with Amplify and QuickSight that helps developers to decrease time to improve user experience. Code is here:
https://github.com/watilde/amplify-observability-example

What observability improves in front-end

Observability in the technical world is a framework that changes its definition depending on the context. John Porcaro published an article called “(re) refine observability” on humio’s blog in 2020 and introduced the below statement as a definition of observability:

“Observability is when you’re able to understand the internal state of a system from the data it provides, and you can explore that data to answer any question about what happened and why.”

https://www.humio.com/whats-new/blog/observability-redefined

In real-world product development, especially in the front-end, their mission is often to provide a better user experience. If we continue the statement to the “so that” part for the front-end, it would look like the below:

So that we can inference what to improve based on data and deliver better experiences in a short time

To understand the current state and come up with a solution in a short time, data needs to be visualized with meaning, and Syslog severity level is often referred to as the best practice to classify logs:

The list of severities is also defined by the standard.
The list of severities is also defined by the standard.
Syslog severity level — Wikipedia

In JavaScript land, we have a console function to output information and that has three levels by default: Errors, Warnings, and Info. From the developer's perspective, people use errors to show thrown Errors, warning as violations of the rules, and info for debugging.

Screenshot of Chrome’s DevTools shows level of log information
Screenshot of Chrome’s DevTools shows level of log information
A screenshot of Chrome’s DevTools shows the level of log information

What information level should we have from the user perspective then? Combining Syslog log level and JavaScript console log level, it can classify as the below:

  1. Console Errors: Emergency to Error level issues that break pages
  2. Console Warnings: Warning level issues that cause lack of user experience
  3. Console Info: Notice to debug level log that does not affect the user experience

How we track them in the front-end is the following: For the first item “Errors”, errors can be caught by onerror and onunhandledrejection. For the second item “Warnings”, we can leverage Web Vitals as metrics that will improve SEO from May 2021. The third item “Info” is mostly for debugging purposes and it even does not affect user experience so that we can forget for now.

What kind of observability exists today

It has been a while since observability became commonplace, and QuickSight seems to play this role, particularly around visualization when using AWS. Its description even says “Scalable, serverless, embeddable, ML-powered BI Service built for the cloud”.

Amazon QuickSight

Amazon QuickSight is a scalable, serverless, embeddable, machine learning-powered business intelligence (BI) service built for the cloud. QuickSight lets you easily create and publish interactive BI dashboards that include Machine Learning-powered insights.

#1 QuickSight 101

Enter AWS with Amplify and integrate QuickSight

AWS has a service called AWS Amplify that consists of a set of tools (open-source framework, admin UI, console) and services (web hosting) to accelerate the development of mobile and web applications on AWS.

AWS Amplify

After trying out AWS Amplify for a while, it turns out Amplify supports Amazon Kinesis Data Streams to deliver logs from the front-end to QuickSight without complicated configuration. Let’s see how to build it in six steps.

Amplify document has a tutorial to start here: https://docs.amplify.aws/start/getting-started/installation/q/integration/js. I would recommend watching the below video to start created by Nader Dabit.

Installing & Configuring the AWS Amplify CLI

Amplify supports Amazon Kinesis Stream. Just run amplify add analytics and you can integrate Amazon Kinesis Stream.

$ npx create-react-app example
$ cd example
$ amplify init
# Put amplifyobservability as name$ amplify add analytics# Select Amazon Kinesis Stream
# Stream name is "amplifyobservabilityKinesis-dev"
$ amplify push

To know which files make errors on what devices, we use StackTrace.JS to standardize error messages and UAParser.js to standardize user agent information. Then let’s make files called “monitorErrors.js” and “monitorWebVitals.js”.

$ npm install stacktrace-js ua-parser-js
$ touch src/monitorErrors.js
$ touch src/monitorWebVitals.js

In monitorWebVitals.js, we configure Kinesis Stream and send standardized error and user-agent:

src/monitorErrors.js

In monitorWebVitals.js, we configure Kinesis Stream and send standardized WebVitals information and user-agent:

src/monitorWebVitals.js

Then we import both of them in src/index.js as like the below:

src/index.js
$ amplify add hosting# Select manual deployment for this time$ amplify publish

After CI/CD works, then you are able to see the app.

Working application

The next step is to set up a data stream from Kinesis Data Streams to QuickSight. It requires a bit of effort to store data in S3 and pull data to QuickSight from S3. The goal image is the below architecture:

Data stream goal image
Data stream goal image
Datastream goal image

5.1 Check the name of Kinesis Data Streams

Open Amazon Kinesis in the management console and select Data Streams from the sidebar. Then you can make sure if the name of Datastream matches in the right panel matches with the codes we implemented.

Checking the name of Kinesis Datastream

5.2 Create Kinesis Data Firehose

Then click Data Firehose from the sidebar and create a new Kinesis Data Firehose delivery stream. That delivers data to S3 through Kinesis Data Stream.

Create Kinesis Data Firehose to deliver data to S3 from Kinesis Data Stream

5.3 Check S3 bucket

Play with the application and let’s send some error data and web vital data. Then you should be able to see the data in S3.

Tracked data in S3

5.4 Setup Glue crawler

The next step is to run a crawler that gathers data from the S3 bucket. AWS Glue helps you to quickly implement it. Open AWS Glue and push “Add crawler” that pulls data from the bucket in S3 you just checked in the previous section.

Glue crawler

5.5 Setup Athena to pull data

Then you are ready to query the data from S3 through AWS Glue by Athena. Just create a new database and connect it with Glue’s data.

Query in Athena

You finally can visualize important data on QuickSight. Make a new board and connect with Athena that shows the below images. It’s good to separate Web Vitals and Error as separated dashboard.

Web Vitals Dashboard
JavaScript Error Dashboard

AWS Amplify Hosting recently adds monitoring capabilities with Amazon CloudWatch integration. We can leverage this feature to see if your service is working.

Monitoring in Amplify

To learn more, you can explore their documentation.

Users are great contributors

In OSS land, we say “given enough eyeballs, all bugs are shallow” as a reason why popular OSS is high quality. We usually do this by beta test. Take a step forward, we can add monitoring as smoke testing in production.

In the other words, the product with real-time JavaScript errors and warnings monitoring can involve more users as great contributors to your product that leads to a better experience.

Acknowledgments

References