We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Internal Monitoring

Beyond what is easily observable from the outside, there are useful things to monitor that live inside the domain of the server's operating system. Things like:

  • Disk usage (i.e., how much data is on disk and how much space is free)
  • Memory used vs. available memory
  • Application logs

AWS doesn't provide these metrics out of the box. To solve this, there are hundreds of options: Grafana, Prometheus, Datadog, Splunk, etc. AWS also provides a simple option with the CloudWatch Agent.

CloudWatch Agent is a small piece of software that takes a single-file configuration and sends information from our server's operating system to AWS. The data can be basic metrics like CPU, disk, and memory usage, or the agent can be configured to upload specific OS or application logs.

Setting up a monitoring agent on an EC2 instance is straightforward:

  1. Grant it the necessary permissions to send data to CloudWatch (via an IAM role and policy).
  2. Install the CloudWatch Agent software on the server.
  3. Configure the agent with a config file that specifies what metrics and logs to collect.
  4. Start the agent, and it will begin sending data to CloudWatch.

Assignment

The PatientPing ops team wants more detailed info on how app servers are behaving. Set up CloudWatch Agent on our EC2 instance.

Cost check: CloudWatch Logs charges $0.50 per GB ingested and $0.03 per GB stored per month. CloudWatch Metrics are free for the first 10 custom metrics.

    1. {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "logs:CreateLogGroup",
              "logs:CreateLogStream",
              "logs:PutLogEvents",
              "logs:DescribeLogStreams"
            ],
            "Resource": ["arn:aws:logs:*:*:*"]
          }
        ]
      }
      
    2. {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Action": ["ssm:GetParameter", "ssm:GetParameters"],
            "Resource": [
              "arn:aws:ssm:*:*:parameter/DATABASE_URL",
              "arn:aws:ssm:*:*:parameter/CMO_NAME"
            ]
          }
        ]
      }
      
      Name this policy patientping-ssm-access.
    1. ssh patientping
      sudo dnf upgrade
      sudo dnf install amazon-cloudwatch-agent
      
    2. sudo nano /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.d/patientping-monitoring.json
      
    3. {
        "agent": {
          "metrics_collection_interval": 60,
          "run_as_user": "root"
        },
        "logs": {
          "logs_collected": {
            "files": {
              "collect_list": [
                {
                  "file_path": "/var/log/patientping.log",
                  "log_group_name": "patientping-monitoring",
                  "log_stream_name": "{instance_id}"
                }
              ]
            }
          }
        },
        "metrics": {
          "append_dimensions": {
            "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
            "ImageId": "${aws:ImageId}",
            "InstanceId": "${aws:InstanceId}",
            "InstanceType": "${aws:InstanceType}"
          },
          "metrics_collected": {
            "mem": { "measurement": ["mem_used_percent"] },
            "swap": { "measurement": ["swap_used_percent"] }
          }
        }
      }
      
    4. sudo systemctl start amazon-cloudwatch-agent
      sudo systemctl enable amazon-cloudwatch-agent
      
    5. cd ~/patientping-web
      PYTHONUNBUFFERED=1 uv run patientping.py 2>&1 | sudo tee -a /var/log/patientping.log
      

Run and submit the CLI tests.

Tip

If you'd rather deal with the IAM role and policy via the CLI, here's some command structure to get you started:

# Create IAM role with trust policy
aws iam create-role --role-name ROLE-NAME --assume-role-policy-document file://TRUST-POLICY.json

# Create and attach inline permissions policy
aws iam put-role-policy --role-name ROLE-NAME --policy-name POLICY-NAME --policy-document file://POLICY.json

# Create IAM instance profile and attach role
aws iam create-instance-profile --instance-profile-name PROFILE-NAME
aws iam add-role-to-instance-profile --instance-profile-name PROFILE-NAME --role-name ROLE-NAME

# Associate instance profile with EC2 instance
aws ec2 associate-iam-instance-profile --instance-id EC2-INSTANCE-ID --iam-instance-profile Name=PROFILE-NAME