AWS Cloud Operations & Migrations Blog

Real User Monitoring with Amazon CloudWatch RUM and Amazon Managed Grafana

In today’s fast-paced digital world, users expect fast and reliable web experiences. Slow-loading pages, errors, and other performance issues can lead to lower engagement and conversion rates, ultimately hurting a business’s bottom line. That’s where Real User Monitoring (RUM) comes in. Real User Monitoring (RUM) is a crucial aspect of modern web application development, allowing developers and operators to gain insights into user experiences and optimize performance. RUM captures and analyzes real-time user data to identify issues, optimize page load time, and reduce errors, leading to improved web performance and user experience.

In this blog post, we will explore how to leverage Amazon CloudWatch RUM and Amazon Managed Grafana to obtain valuable metrics and visualizations for your applications. CloudWatch RUM gives rich insights into user experiences by capturing real-time client-side data like page load times, errors, and user flows. However, Amazon CloudWatch has limited visualization capabilities for time series data. This is where Grafana can complement CloudWatch by providing more flexible, full-featured data visualizations and dashboards.

Amazon Managed Grafana is a fully managed service for Grafana that is a popular open-source analytics platform that enables you to query, visualize, and alert on your metrics, logs, and traces. Grafana also enables building custom visualizations, dashboards, and alerts to deeply analyze trends and correlations across different monitoring data sources. Customers who want to use open-source monitoring leverage Grafana’s flexible data ingestion and visualization capabilities. By integrating CloudWatch RUM data into existing Grafana analysis, operators can connect user experience analytics with other application and infrastructure telemetry for a unified view. Amazon Managed Grafana greatly simplifies deploying and managing Grafana, allowing focus to shift to building custom RUM-driven dashboards.

We will guide you through the process of deploying the AWS Bookstore Demo App using AWS CloudFormation, configuring Amazon CloudWatch RUM to collect user behavior data, setting up an Amazon Managed Grafana workspace, and using CloudWatch as the data source, building visualizations of performance metrics, and analyzing the data to understand and optimize the application experience.

Prerequisites

Before diving into the setup, ensure you have the following prerequisites in place:

  • An AWS account.
  • AWS CLI version 2.
  • Basic knowledge of AWS services, including CloudFormation, CloudWatch, and Amazon Managed Grafana.
  • Familiarity with web application development and JavaScript.

Bootstrap the environment

To get started, let’s deploy the AWS Bookstore Demo App, which serves as our sample application for this tutorial. This is provided as a sample. If you have other application, feel free to use it. We will use the AWS Bookstore Demo App from GitHub

Solution diagram showcasing real user monitoring with CloudWatch RUM and Amazon Managed Grafana

Figure 1: Real User Monitoring using CloudWatch RUM and Amazon Managed Grafana

First, let’s declare the necessary environment variables:

export APP_NAME=MyBookstore # Demo App Name export AWS_REGION=us-west-2 # Replace with your desired AWS Region export ACCOUNT_ID=123456789 # Replace with your own AWS Account ID

Let’s use the AWS CloudFormation template to deploy the aws-bookstore-demo-app.

aws cloudformation create-stack --stack-name $APP_NAME --template-url https://s3.amazonaws.com/aws-bookstore-demo-app-us-east-1/master-fullstack.yaml --region $AWS_REGION --capabilities CAPABILITY_NAMED_IAM

You can use the list-stack command to check on the status.

aws cloudformation list-stacks

This should show the update like following. Refer “StackStatus” field for the latest status.

{
"StackSummaries": [
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789:stack/MyBookstore-BookstoreCognitoDefaultUser-1TYWFLIG2X5SQ/bc9abc20-0013-11ee-b39e-02bcf8dead33",
"StackName": "MyBookstore-BookstoreCognitoDefaultUser-1TYWFLIG2X5SQ",
"TemplateDescription": "Custom Resource to Create a New Cognito User",
"CreationTime": "2023-06-01T00:32:06.514000+00:00",
"StackStatus": "CREATE_COMPLETE",
"ParentId": "arn:aws:cloudformation:us-west-2:123456789:stack/MyBookstore/70ae6500-0013-11ee-b728-06038723fe29",
"RootId": "arn:aws:cloudformation:us-west-2:123456789:stack/MyBookstore/70ae6500-0013-11ee-b728-06038723fe29",
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
},
{
"StackId": "arn:aws:cloudformation:us-west-2:123456789:stack/MyBookstore/70ae6500-0013-11ee-b728-06038723fe29",
"StackName": "MyBookstore",
"CreationTime": "2023-06-01T00:31:55.952000+00:00",
"StackStatus": "CREATE_IN_PROGRESS",
"DriftInformation": {
"StackDriftStatus": "NOT_CHECKED"
}
}
]
}

This typically takes around 20 minutes for the CloudFormation stack to complete and to create resources. Once the stack creation is complete, note the Amazon CloudFront URL provided in the CloudFormation outputs. This URL will serve as the entry point to the deployed application. You can get the endpoint as below.

export BKST_CLOUDFRONT_URL=`aws cloudformation describe-stacks --query "Stacks[1].Outputs[OutputKey==\\\`WebApplication\\\`].OutputValue" --output text

Try that endpoint in your browser. You can use any email to sign up and explore the demo application.

Screenshot of Bookstore Demo application home page

Figure 2: Bookstore Demo application homepage

Configuring Amazon CloudWatch RUM

Now that the demo application is up and running, follow below steps to configure CloudWatch RUM to capture user behavior and performance metrics by creating a new app monitor.

  1. Navigate to Amazon CloudWatch in the AWS Management Console.
  2. Under Application Monitoring section go to RUM. Then click on Add App Monitor.
  3. Provide the app monitor name and application domain (CloudFront URL as mentioned previously) values.

Rest of the values can be default and click on Add App Monitor as below.

Screenshot of CloudWatch RUM "Add app monitor" section

Figure 3: App monitor section in CloudWatch RUM

To enable CloudWatch RUM monitoring for your application, you need to add the JavaScript snippet in your front-end resources.

  1. Navigate to the CloudWatch console and select RUM.
  2. Select the MyBookstore application.
  3. Click on the Configuration tab.
  4. Under JavaScript snippet, go to the HTML section.
  5. Copy the JavaScript code provided in the HTML section.
  6. Paste this JavaScript snippet into the frontend resources of your application to enable CloudWatch RUM monitoring.
Screenshot of Javascript snippet section under RUM configuration section.

Figure 4: MyBookstore configuration section in CloudWatch RUM

Please refer Insert the code snippet into your application to insert copied JavaScript snippet into your application.

To add the code snippet to the bookstore demo app, we will use AWS CodePipeline. Please follow the below steps.

  1. Go to the AWS Management Console and open AWS CodePipeline.
  2. Click on the pipeline called mybookstore-Assets-pipeline. This will take you to the source code in AWS CodeCommit.
  3. Navigate to the public/index.html file. Edit this file and paste the JavaScript snippet inside the <head> tag.
Screenshot of my bookstore-WebAssets index.html code section under CodeCommit.

Figure 5: MyBookstore Repositories section in CodeCommit

This will trigger the build automatically from the CodePipeline as below. Updated artifacts are available from the CloudFront URL as well.

Screenshot of Pipeline section under CodePipeline.

Figure 6: MyBookstore Pipelines section in CodePipeline

Now, you can navigate to different pages in your application using that CloudFront URL in your browser. As you navigate to pages like the homepage, product listing, and product detail pages, the CloudWatch RUM client will automatically capture page load metrics for each pageview. To validate that the deployment of the CloudWatch RUM client was successful, go to the CloudWatch RUM console. You should see metrics like page loads, average page load speed, page loads and load time, and any JavaScript errors encountered. Metrics should be populated from your application pages.

Screenshot of CloudWatch RUM overview section.

Figure 7: CloudWatch RUM overview dashboard

Configuring Amazon Managed Grafana

Refer to Amazon Managed Grafana – Getting Started for information on how to configure and set up Amazon Managed Grafana. Amazon Managed Grafana lets you to configure user access through AWS IAM Identity Center or other SAML based Identity Providers (IdP).

To visualize the RUM metrics collected by CloudWatch, we will now set up an Amazon Managed Grafana workspace and configure CloudWatch as the data source. Let’s create an AWS Identity and Access Management (IAM) role as following and then create the workspace.

cat << EOF > grafana_trust_policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "grafana.amazonaws.com"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "${ACCOUNT_ID}"
                },
                "StringLike": {
                    "aws:SourceArn": "arn:aws:grafana:${AWS_REGION}:${ACCOUNT_ID}:/workspaces/*"
                }
            }
        }
    ]
}
EOF

aws iam create-role --role-name cw-rum-grafana-role --assume-role-policy-document file://grafana_trust_policy.json
aws iam attach-role-policy --role-name cw-rum-grafana-role --policy-arn arn:aws:iam::aws:policy/CloudWatchFullAccess
aws iam attach-role-policy --role-name cw-rum-grafana-role --policy-arn arn:aws:iam::aws:policy/AmazonCloudWatchRUMFullAccess
aws iam attach-role-policy --role-name cw-rum-grafana-role --policy-arn arn:aws:iam::aws:policy/CloudWatchAutomaticDashboardsAccess 

RESULT=$(aws grafana create-workspace --account-access-type "CURRENT_ACCOUNT" --authentication-providers "AWS_SSO" --permission-type "SERVICE_MANAGED"  --workspace-name "$APP_NAME" --workspace-role-arn "cw-rum-grafana-role")
export WORKSPACE_ID=$(jq -r .workspace.id <<< $RESULT)
 
while true; do
    STATUS=$(aws grafana describe-workspace --workspace-id $WORKSPACE_ID | jq -r .workspace.status)
    if [[ "${STATUS}" == "ACTIVE" ]]; then break; fi
    sleep 1
    echo -n '.'
done

export WORKSPACE_ENDPOINT=$(aws grafana describe-workspace --workspace-id $WORKSPACE_ID | jq -r .workspace.endpoint)

Now, you can sign into Amazon Managed Grafana using the WORKSPACE_ENDPOINT value. The URL looks like this “https://g-xxxx.grafana-workspace.YOUR_AWS_REGION.amazonaws.com/login”

After successful login, click on Data sources and add a new CloudWatch Data source. Choose your region and enter “AWS/RUM” as the namespace. Now, click Save to continue.

Screenshot of Grafana data source section to configure CloudWatch RUM datasource.

Figure 9: Adding CloudWatch RUM as Data Source in Amazon Managed Grafana

You can click on explore button and choose the metric name to see the results. For example, the metric name PerformanceNavigationDuration under AWS/RUM namespace will show like this.

Screenshot of RUM dashboard with performanceNavigationDuration metrics in Grafana console.

Figure 10: Metrics explore view in Amazon Managed Grafana

To create the Grafana dashboard, you can download this JSON file  and then proceed to import it. To import the dashboard JSON file, click on the Dashboards link and create new dashboard by clicking Import option from the drop down as shown below.

Screenshot of Import dashboard section to import RUM dashboard json file.

Figure 11: Importing Pre-build RUM dashboard into Amazon Managed Grafana

Once the dashboard JSON is imported, RUM metrics will be populated automatically as shown below.

Screenshot of RUM dashboard with important metrics shown on the dashboard.

Figure 12: CloudWatch RUM dashboard view in Amazon Managed Grafana

With CloudWatch RUM and Amazon Managed Grafana set up, you have the ability to analyze and monitor the performance and behavior of your deployed application. You can use the dashboards and visualizations available within Amazon Managed Grafana to gain valuable insights and make data-driven decisions. You can explore the RUM, metrics such as page load time, resource timings, and user sessions, to identify potential bottlenecks and areas for optimization. With Amazon Managed Grafana, you can customize your dashboards, create alerts, and share insights with your team. Please refer the Building Dashboards and Alerts in Grafana documentation for more information.

Cleanup

To clean up the resources created and to avoid charges, use the below commands.

aws grafana delete-workspace --workspace-id $WORKSPACE_ID
aws iam delete-role --role-name cw-rum-grafana-role --region $AWS_REGION
aws rum delete-app-monitor --name=<<name>> --region $AWS_REGION
aws cloudformation delete-stack --stack-name $APP_NAME --region $AWS_REGION

Conclusion

Real User Monitoring is a critical aspect of ensuring optimal user experiences and performance for web applications. By combining the power of Amazon CloudWatch RUM and Amazon Managed Grafana, you can gain valuable insights into user behavior and application performance. In this blog post, we covered the entire process from deploying the demo application to configuring Amazon CloudWatch RUM for data collection. We also set up an Amazon Managed Grafana workspace, configured CloudWatch as the data source, and visualized the collected metrics.

By following these steps, you now have the tools and the knowledge to implement real user monitoring for your own applications and utilize Amazon Managed Grafana to analyze and optimize performance. You should regularly monitor your RUM metrics and make informed decisions to enhance user experiences and ensure the success of your web applications.

To get started with CloudWatch RUM, see Use CloudWatch RUM. To get hands-on experience on AWS services for Observability, check out the One Observability Workshop. To learn more about monitoring best practices in AWS, check the AWS Observability Best Practices guide.

About the authors

Ganesh Sambandan

Ganesh Sambandan

Ganesh Sambandan is a Technical Account Manager for strategic customers at AWS, where he assists organizations in implementing best practices for running workloads on AWS. He is also a Technical Field Community (TFC) member in cloud operations domain at AWS. Based in Phoenix, Arizona, you can connect with him on Linkedin at: linkedin.com/in/ganeshsambandan.

Siva Guruvareddiar

Siva Guruvareddiar is a Senior Solutions Architect at AWS where he is passionate about helping customers architect highly available systems. He helps speed cloud-native adoption journeys by modernizing platform infrastructure and internal architecture using microservices, containerization, observability, service mesh areas, and cloud migration. Connect on LinkedIn at: linkedin.com/in/sguruvar.

Munish Dabra

Munish Dabra is a Principal Solutions Architect at Amazon Web Services (AWS). His current areas of focus are AI/ML and Observability. He has a strong background in designing and building scalable distributed systems. He enjoys helping customers innovate and transform their business in AWS. LinkedIn: /mdabra.