📝

Fargate で ps コマンドを実行した結果を CloudWatch メトリクスにしてみた

に公開

前提

  • コンテナイメージなどの作成環境: Cloud9
  • ECR リポジトリは作成済み

コンテナイメージの作成

以下のスクリプトファイルでは 1 分ごとに ps コマンドを実行して、最も高い値を CloudWatch メトリクスに送信しています。

top-monitor.sh
#!/bin/bash

while true; do
  timestamp=$(date +%s)

  cpu=$(ps -eo pid,comm,%cpu --sort=-%cpu | awk 'NR==2 { print $3 }')
  mem=$(ps -eo pid,comm,%mem --sort=-%mem | awk 'NR==2 { print $3 }')

  echo "Sending CPU usage: $cpu"
  echo "Sending MEM usage: $mem"

  aws cloudwatch put-metric-data \
    --namespace "MyApp/TopMetrics" \
    --metric-name TopProcessCPU \
    --value "$cpu" \
    --timestamp "$timestamp"

  aws cloudwatch put-metric-data \
    --namespace "MyApp/TopMetrics" \
    --metric-name TopProcessMEM \
    --value "$mem" \
    --timestamp "$timestamp"

  sleep 60
done
Dockerfile
FROM amazonlinux:2

# 必要なツールのインストール
RUN yum install -y procps aws-cli

# スクリプトを追加
COPY top-monitor.sh /usr/local/bin/top-monitor.sh
RUN chmod +x /usr/local/bin/top-monitor.sh

# 1分ごとにスクリプトを実行
CMD [ "sh", "-c", "while true; do /usr/local/bin/top-monitor.sh; sleep 60; done" ]
# ECR リポジトリにプッシュ
$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 012345678901.dkr.ecr.ap-northeast-1.amazonaws.com

$ docker build -t test .

$ docker tag test:latest 012345678901.dkr.ecr.ap-northeast-1.amazonaws.com/test:latest

$ docker push 012345678901.dkr.ecr.ap-northeast-1.amazonaws.com/test:latest

Fargate タスクの作成

タスク定義で上記イメージを指定します。
その他のタスク定義の設定はデフォルトです。

タスク定義
{
    "taskDefinitionArn": "xxx",
    "containerDefinitions": [
        {
            "name": "test",
            "image": "xxx",
            "cpu": 0,
            "portMappings": [
                {
                    "name": "test-80-tcp",
                    "containerPort": 80,
                    "hostPort": 80,
                    "protocol": "tcp",
                    "appProtocol": "http"
                }
            ],
            "essential": true,
            "environment": [],
            "environmentFiles": [],
            "mountPoints": [],
            "volumesFrom": [],
            "ulimits": [],
            "logConfiguration": {
                "logDriver": "awslogs",
                "options": {
                    "awslogs-group": "/ecs/test",
                    "mode": "non-blocking",
                    "awslogs-create-group": "true",
                    "max-buffer-size": "25m",
                    "awslogs-region": "ap-northeast-1",
                    "awslogs-stream-prefix": "ecs"
                },
                "secretOptions": []
            },
            "systemControls": []
        }
    ],
    "family": "test",
    "taskRoleArn": "xxx",
    "executionRoleArn": "xxx",
    "networkMode": "awsvpc",
    "revision": 74,
    "volumes": [],
    "status": "ACTIVE",
    "requiresAttributes": [
        {
            "name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
        },
        {
            "name": "ecs.capability.execution-role-awslogs"
        },
        {
            "name": "com.amazonaws.ecs.capability.ecr-auth"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.28"
        },
        {
            "name": "com.amazonaws.ecs.capability.task-iam-role"
        },
        {
            "name": "ecs.capability.execution-role-ecr-pull"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
        },
        {
            "name": "ecs.capability.task-eni"
        },
        {
            "name": "com.amazonaws.ecs.capability.docker-remote-api.1.29"
        }
    ],
    "placementConstraints": [],
    "compatibilities": [
        "EC2",
        "FARGATE"
    ],
    "requiresCompatibilities": [
        "FARGATE"
    ],
    "cpu": "1024",
    "memory": "3072",
    "runtimePlatform": {
        "cpuArchitecture": "X86_64",
        "operatingSystemFamily": "LINUX"
    },
    "registeredAt": "2025-06-09T10:06:09.192Z",
    "registeredBy": "xxx",
    "enableFaultInjection": false,
    "tags": []
}

上記タスク定義を使用してタスクを起動します。

$ aws ecs run-task \
--cluster test \
--launch-type FARGATE \
--task-definition my-task-def:1 \
--network-configuration "awsvpcConfiguration={subnets=[my-subnet-id],securityGroups=[my-sg-id],assignPublicIp=ENABLED}" \
--enable-execute-command \
--count 1

タスクの起動後、CloudWatch Logs のロググループに以下のようなログが出力されます。

Sending CPU usage: 0.0
Sending MEM usage: 0.0

また、CloudWatch メトリクスのカスタム名前空間にもメトリクスが表示されます。

まとめ

今回は Fargate で ps コマンドを実行した結果を CloudWatch メトリクスにしてみました。
どなたかの参考になれば幸いです。

Discussion