diff --git a/.gitignore b/.gitignore index 107bc8d..54e8f0c 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ dependencies-stamp *.tar.gz /vendor .idea + +cdk.out diff --git a/ecscollector/testdata/fixtures/ec2_task_metadata.json b/ecscollector/testdata/fixtures/ec2_task_metadata.json index 5c7f869..a188a1a 100644 --- a/ecscollector/testdata/fixtures/ec2_task_metadata.json +++ b/ecscollector/testdata/fixtures/ec2_task_metadata.json @@ -1,229 +1,259 @@ { - "Cluster": "prom-ecs-exporter-sandbox", - "TaskARN": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/506f22fab0414cde856201584703fed9", - "Family": "prom-ecs-exporter-sandbox-main-ec2", - "Revision": "13", + "Cluster": "prom-ecs-exporter-fixtures", + "TaskARN": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb", + "Family": "ecs-exporter-fixtures-ec2", + "Revision": "4", "DesiredStatus": "RUNNING", "KnownStatus": "RUNNING", - "PullStartedAt": "2025-02-27T05:09:52.332595252Z", - "PullStoppedAt": "2025-02-27T05:10:01.206072368Z", + "Limits": { + "Memory": 256 + }, + "PullStartedAt": "2025-04-28T02:04:56.203269242Z", + "PullStoppedAt": "2025-04-28T02:05:03.516794491Z", "AvailabilityZone": "us-east-1a", "LaunchType": "EC2", "Containers": [ { - "DockerId": "213e1203f4bb72af185724d937e698d2724acf35b57ec2dd5f3c963adbd2d38c", - "Name": "nonessential", - "DockerName": "ecs-prom-ecs-exporter-sandbox-main-ec2-13-nonessential-9c9ab8aeb0e0dbdca601", - "Image": "alpine", - "ImageID": "sha256:8d591b0b7dea080ea3be9e12ae563eebf9869168ffced1cb25b2470a3d9fe15e", + "DockerId": "559f4af51a2f85286138de04fbe2892348128ed55dbf24033bc6a1a3eb6f1d7f", + "Name": "ecs-exporter", + "DockerName": "ecs-ecs-exporter-fixtures-ec2-4-ecs-exporter-f8a886e3c3d191f72100", + "Image": "quay.io/prometheuscommunity/ecs-exporter:v0.4.0", + "ImageID": "sha256:bedb26ec39cf3d7fac4602a633a275df7227c84b3e4b320712b60a510416420f", "Labels": { - "com.amazonaws.ecs.cluster": "prom-ecs-exporter-sandbox", - "com.amazonaws.ecs.container-name": "nonessential", - "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/506f22fab0414cde856201584703fed9", - "com.amazonaws.ecs.task-definition-family": "prom-ecs-exporter-sandbox-main-ec2", - "com.amazonaws.ecs.task-definition-version": "13" + "com.amazonaws.ecs.cluster": "prom-ecs-exporter-fixtures", + "com.amazonaws.ecs.container-name": "ecs-exporter", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb", + "com.amazonaws.ecs.task-definition-family": "ecs-exporter-fixtures-ec2", + "com.amazonaws.ecs.task-definition-version": "4" }, "DesiredStatus": "RUNNING", - "KnownStatus": "STOPPED", - "ExitCode": 0, + "KnownStatus": "RUNNING", "Limits": { "CPU": 128, - "Memory": 256 + "Memory": 128 }, - "CreatedAt": "2025-02-27T05:09:54.959587312Z", - "StartedAt": "2025-02-27T05:09:56.392336771Z", - "FinishedAt": "2025-02-27T05:09:56.409399983Z", + "CreatedAt": "2025-04-28T02:05:03.535090427Z", + "StartedAt": "2025-04-28T02:05:03.749856806Z", "Type": "NORMAL", "Volumes": [ { - "Source": "/var/lib/ecs/deps/execute-command/config/amazon-ssm-agent-Orvj12YkCf4DKDu1cHTOVj7smDviWx1T4Kg3Q_IdNYA=.json", - "Destination": "/ecs-execute-command-636764d0-0d77-44c1-96b2-207c74034dff/configuration/amazon-ssm-agent.json" + "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/amazon-ssm-agent", + "Destination": "/ecs-execute-command-c475367c-67a3-4a69-83e1-03d6d897e13e/amazon-ssm-agent" }, { - "Source": "/var/lib/ecs/deps/execute-command/config/seelog-gEZ-TIvHAyOLfMC5wiWRofgDMlDzaCZ6zcswnAoop84=.xml", - "Destination": "/ecs-execute-command-636764d0-0d77-44c1-96b2-207c74034dff/configuration/seelog.xml" + "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-agent-worker", + "Destination": "/ecs-execute-command-c475367c-67a3-4a69-83e1-03d6d897e13e/ssm-agent-worker" }, { - "Source": "/var/lib/ecs/deps/execute-command/certs/tls-ca-bundle.pem", - "Destination": "/ecs-execute-command-636764d0-0d77-44c1-96b2-207c74034dff/certs/amazon-ssm-agent.crt" + "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-session-worker", + "Destination": "/ecs-execute-command-c475367c-67a3-4a69-83e1-03d6d897e13e/ssm-session-worker" }, { - "Source": "/var/log/ecs/exec/506f22fab0414cde856201584703fed9/nonessential", - "Destination": "/var/log/amazon/ssm" + "Source": "/var/lib/ecs/deps/execute-command/config/amazon-ssm-agent-Orvj12YkCf4DKDu1cHTOVj7smDviWx1T4Kg3Q_IdNYA=.json", + "Destination": "/ecs-execute-command-c475367c-67a3-4a69-83e1-03d6d897e13e/configuration/amazon-ssm-agent.json" }, { - "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/amazon-ssm-agent", - "Destination": "/ecs-execute-command-636764d0-0d77-44c1-96b2-207c74034dff/amazon-ssm-agent" + "Source": "/var/lib/ecs/deps/execute-command/config/seelog-gEZ-TIvHAyOLfMC5wiWRofgDMlDzaCZ6zcswnAoop84=.xml", + "Destination": "/ecs-execute-command-c475367c-67a3-4a69-83e1-03d6d897e13e/configuration/seelog.xml" }, { - "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-agent-worker", - "Destination": "/ecs-execute-command-636764d0-0d77-44c1-96b2-207c74034dff/ssm-agent-worker" + "Source": "/var/lib/ecs/deps/execute-command/certs/tls-ca-bundle.pem", + "Destination": "/ecs-execute-command-c475367c-67a3-4a69-83e1-03d6d897e13e/certs/amazon-ssm-agent.crt" }, { - "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-session-worker", - "Destination": "/ecs-execute-command-636764d0-0d77-44c1-96b2-207c74034dff/ssm-session-worker" + "Source": "/var/log/ecs/exec/1e76d951e76c4ea5ad410966ffde3bdb/ecs-exporter", + "Destination": "/var/log/amazon/ssm" } ], - "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-sandbox/506f22fab0414cde856201584703fed9/80b5fc27-0113-4b4f-83a4-f3d4b4b2b016", + "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb/7af5aa98-978a-4b49-b808-e0f2f24238c2", "Networks": [ { - "NetworkMode": "bridge", + "NetworkMode": "awsvpc", "IPv4Addresses": [ - "" - ] + "10.0.178.177" + ], + "AttachmentIndex": 0, + "MACAddress": "0a:ff:c0:bd:cb:53", + "IPv4SubnetCIDRBlock": "10.0.128.0/17", + "PrivateDNSName": "ip-10-0-178-177.ec2.internal", + "SubnetGatewayIpv4Address": "10.0.128.1/17" } ] }, { - "DockerId": "01cf1f3208005cda71d5ac936ded65d2ecc0a8cc8ff8a82d2e00410bf4fbbd6d", - "Name": "ecs-exporter", - "DockerName": "ecs-prom-ecs-exporter-sandbox-main-ec2-13-ecs-exporter-e2aeb1e6be8998c72300", - "Image": "quay.io/prometheuscommunity/ecs-exporter:main", - "ImageID": "sha256:1585460bf5becf755c9f45fa931283546ca62e2d51bb638010c8958158d144bc", - "Ports": [ - { - "ContainerPort": 9779, - "Protocol": "tcp", - "HostPort": 32768, - "HostIp": "0.0.0.0" - }, - { - "ContainerPort": 9779, - "Protocol": "tcp", - "HostPort": 32768, - "HostIp": "::" - } - ], + "DockerId": "d3b4c06f3fe8614d958ed27f7f3e40adc3b252793399741a92f0935fb60fb5a8", + "Name": "main", + "DockerName": "ecs-ecs-exporter-fixtures-ec2-4-main-c0d28ea4b8e4b68e2500", + "Image": "alpine", + "ImageID": "sha256:8d591b0b7dea080ea3be9e12ae563eebf9869168ffced1cb25b2470a3d9fe15e", "Labels": { - "com.amazonaws.ecs.cluster": "prom-ecs-exporter-sandbox", - "com.amazonaws.ecs.container-name": "ecs-exporter", - "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/506f22fab0414cde856201584703fed9", - "com.amazonaws.ecs.task-definition-family": "prom-ecs-exporter-sandbox-main-ec2", - "com.amazonaws.ecs.task-definition-version": "13" + "com.amazonaws.ecs.cluster": "prom-ecs-exporter-fixtures", + "com.amazonaws.ecs.container-name": "main", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb", + "com.amazonaws.ecs.task-definition-family": "ecs-exporter-fixtures-ec2", + "com.amazonaws.ecs.task-definition-version": "4" }, "DesiredStatus": "RUNNING", "KnownStatus": "RUNNING", "Limits": { - "CPU": 128, - "Memory": 256 + "CPU": 2, + "Memory": 0 }, - "CreatedAt": "2025-02-27T05:10:00.313953836Z", - "StartedAt": "2025-02-27T05:10:02.731563327Z", + "CreatedAt": "2025-04-28T02:04:56.308600111Z", + "StartedAt": "2025-04-28T02:04:56.505535488Z", "Type": "NORMAL", "Volumes": [ { - "Source": "/var/lib/ecs/deps/execute-command/config/seelog-gEZ-TIvHAyOLfMC5wiWRofgDMlDzaCZ6zcswnAoop84=.xml", - "Destination": "/ecs-execute-command-36dfb910-8e80-47b9-8b3a-12c7308123b2/configuration/seelog.xml" + "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/amazon-ssm-agent", + "Destination": "/ecs-execute-command-41acb996-dcb3-4bbf-b998-6fd60e92b9f9/amazon-ssm-agent" }, { - "Source": "/var/lib/ecs/deps/execute-command/certs/tls-ca-bundle.pem", - "Destination": "/ecs-execute-command-36dfb910-8e80-47b9-8b3a-12c7308123b2/certs/amazon-ssm-agent.crt" + "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-agent-worker", + "Destination": "/ecs-execute-command-41acb996-dcb3-4bbf-b998-6fd60e92b9f9/ssm-agent-worker" }, { - "Source": "/var/log/ecs/exec/506f22fab0414cde856201584703fed9/ecs-exporter", - "Destination": "/var/log/amazon/ssm" + "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-session-worker", + "Destination": "/ecs-execute-command-41acb996-dcb3-4bbf-b998-6fd60e92b9f9/ssm-session-worker" }, { - "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/amazon-ssm-agent", - "Destination": "/ecs-execute-command-36dfb910-8e80-47b9-8b3a-12c7308123b2/amazon-ssm-agent" + "Source": "/var/lib/ecs/deps/execute-command/config/amazon-ssm-agent-Orvj12YkCf4DKDu1cHTOVj7smDviWx1T4Kg3Q_IdNYA=.json", + "Destination": "/ecs-execute-command-41acb996-dcb3-4bbf-b998-6fd60e92b9f9/configuration/amazon-ssm-agent.json" }, { - "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-agent-worker", - "Destination": "/ecs-execute-command-36dfb910-8e80-47b9-8b3a-12c7308123b2/ssm-agent-worker" + "Source": "/var/lib/ecs/deps/execute-command/config/seelog-gEZ-TIvHAyOLfMC5wiWRofgDMlDzaCZ6zcswnAoop84=.xml", + "Destination": "/ecs-execute-command-41acb996-dcb3-4bbf-b998-6fd60e92b9f9/configuration/seelog.xml" }, { - "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-session-worker", - "Destination": "/ecs-execute-command-36dfb910-8e80-47b9-8b3a-12c7308123b2/ssm-session-worker" + "Source": "/var/lib/ecs/deps/execute-command/certs/tls-ca-bundle.pem", + "Destination": "/ecs-execute-command-41acb996-dcb3-4bbf-b998-6fd60e92b9f9/certs/amazon-ssm-agent.crt" }, { - "Source": "/var/lib/ecs/deps/execute-command/config/amazon-ssm-agent-Orvj12YkCf4DKDu1cHTOVj7smDviWx1T4Kg3Q_IdNYA=.json", - "Destination": "/ecs-execute-command-36dfb910-8e80-47b9-8b3a-12c7308123b2/configuration/amazon-ssm-agent.json" + "Source": "/var/log/ecs/exec/1e76d951e76c4ea5ad410966ffde3bdb/main", + "Destination": "/var/log/amazon/ssm" } ], - "LogDriver": "awslogs", - "LogOptions": { - "awslogs-group": "EcsExporterCdkStack-promecsexportersandboxmainec2taskdefinitionpromecsexportersandboxmainec2ecsexporterLogGroup874A22EF-y3iGqSSTf3sz", - "awslogs-region": "us-east-1", - "awslogs-stream": "ecs-exporter/ecs-exporter/506f22fab0414cde856201584703fed9" - }, - "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-sandbox/506f22fab0414cde856201584703fed9/5fba1957-462a-48b2-9295-8602b69e00be", + "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb/e09dd682-65fd-4d9f-a2bd-2707fd62fb7e", "Networks": [ { - "NetworkMode": "bridge", + "NetworkMode": "awsvpc", "IPv4Addresses": [ - "172.17.0.2" - ] + "10.0.178.177" + ], + "AttachmentIndex": 0, + "MACAddress": "0a:ff:c0:bd:cb:53", + "IPv4SubnetCIDRBlock": "10.0.128.0/17", + "PrivateDNSName": "ip-10-0-178-177.ec2.internal", + "SubnetGatewayIpv4Address": "10.0.128.1/17" } ] }, { - "DockerId": "6b80adab0733f579594eccae31e5b0056b9544b805450ad6e278fed7f5e1c5ba", - "Name": "prometheus", - "DockerName": "ecs-prom-ecs-exporter-sandbox-main-ec2-13-prometheus-86f1e9bab7a8e9a65400", - "Image": "prom/prometheus:v3.1.0", - "ImageID": "sha256:f3d60e89ba2d4a402d1c62dccdab300f81579355e0744670c55b9ba282f3b56d", + "DockerId": "74d72daf3420705c7038b9f11295b4d951ca32c4f71f1ff6e3abe58202abc093", + "Name": "nonessential", + "DockerName": "ecs-ecs-exporter-fixtures-ec2-4-nonessential-94b3bf8585e3e8bec001", + "Image": "alpine", + "ImageID": "sha256:8d591b0b7dea080ea3be9e12ae563eebf9869168ffced1cb25b2470a3d9fe15e", "Labels": { - "com.amazonaws.ecs.cluster": "prom-ecs-exporter-sandbox", - "com.amazonaws.ecs.container-name": "prometheus", - "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/506f22fab0414cde856201584703fed9", - "com.amazonaws.ecs.task-definition-family": "prom-ecs-exporter-sandbox-main-ec2", - "com.amazonaws.ecs.task-definition-version": "13" + "com.amazonaws.ecs.cluster": "prom-ecs-exporter-fixtures", + "com.amazonaws.ecs.container-name": "nonessential", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb", + "com.amazonaws.ecs.task-definition-family": "ecs-exporter-fixtures-ec2", + "com.amazonaws.ecs.task-definition-version": "4" }, "DesiredStatus": "RUNNING", - "KnownStatus": "RUNNING", + "KnownStatus": "STOPPED", + "ExitCode": 0, "Limits": { "CPU": 128, - "Memory": 256 + "Memory": 128 }, - "CreatedAt": "2025-02-27T05:10:01.22383376Z", - "StartedAt": "2025-02-27T05:10:02.730952683Z", + "CreatedAt": "2025-04-28T02:04:56.297553357Z", + "StartedAt": "2025-04-28T02:04:56.520475713Z", + "FinishedAt": "2025-04-28T02:04:56.518937243Z", "Type": "NORMAL", "Volumes": [ { - "DockerName": "b4c23c0b1e1cea0ddfeab13122e911c7f52eb67720d3ffb43adba63b817e6a1e", - "Source": "/var/lib/docker/volumes/b4c23c0b1e1cea0ddfeab13122e911c7f52eb67720d3ffb43adba63b817e6a1e/_data", - "Destination": "/prometheus" + "Source": "/var/lib/ecs/deps/execute-command/certs/tls-ca-bundle.pem", + "Destination": "/ecs-execute-command-e70b4983-0ed3-4602-8110-e8b7c82a6e3e/certs/amazon-ssm-agent.crt" + }, + { + "Source": "/var/log/ecs/exec/1e76d951e76c4ea5ad410966ffde3bdb/nonessential", + "Destination": "/var/log/amazon/ssm" }, { "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/amazon-ssm-agent", - "Destination": "/ecs-execute-command-12f856a9-3af4-4de7-ab82-671147b2a114/amazon-ssm-agent" + "Destination": "/ecs-execute-command-e70b4983-0ed3-4602-8110-e8b7c82a6e3e/amazon-ssm-agent" }, { "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-agent-worker", - "Destination": "/ecs-execute-command-12f856a9-3af4-4de7-ab82-671147b2a114/ssm-agent-worker" + "Destination": "/ecs-execute-command-e70b4983-0ed3-4602-8110-e8b7c82a6e3e/ssm-agent-worker" }, { "Source": "/var/lib/ecs/deps/execute-command/bin/3.3.1802.0/ssm-session-worker", - "Destination": "/ecs-execute-command-12f856a9-3af4-4de7-ab82-671147b2a114/ssm-session-worker" + "Destination": "/ecs-execute-command-e70b4983-0ed3-4602-8110-e8b7c82a6e3e/ssm-session-worker" }, { "Source": "/var/lib/ecs/deps/execute-command/config/amazon-ssm-agent-Orvj12YkCf4DKDu1cHTOVj7smDviWx1T4Kg3Q_IdNYA=.json", - "Destination": "/ecs-execute-command-12f856a9-3af4-4de7-ab82-671147b2a114/configuration/amazon-ssm-agent.json" + "Destination": "/ecs-execute-command-e70b4983-0ed3-4602-8110-e8b7c82a6e3e/configuration/amazon-ssm-agent.json" }, { "Source": "/var/lib/ecs/deps/execute-command/config/seelog-gEZ-TIvHAyOLfMC5wiWRofgDMlDzaCZ6zcswnAoop84=.xml", - "Destination": "/ecs-execute-command-12f856a9-3af4-4de7-ab82-671147b2a114/configuration/seelog.xml" - }, - { - "Source": "/var/lib/ecs/deps/execute-command/certs/tls-ca-bundle.pem", - "Destination": "/ecs-execute-command-12f856a9-3af4-4de7-ab82-671147b2a114/certs/amazon-ssm-agent.crt" - }, - { - "Source": "/var/log/ecs/exec/506f22fab0414cde856201584703fed9/prometheus", - "Destination": "/var/log/amazon/ssm" + "Destination": "/ecs-execute-command-e70b4983-0ed3-4602-8110-e8b7c82a6e3e/configuration/seelog.xml" } ], - "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-sandbox/506f22fab0414cde856201584703fed9/7ae35d49-867b-468f-afef-916925db8dca", + "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb/b6d4de7e-b022-4721-abd5-4a432ecd6797", + "Networks": [ + { + "NetworkMode": "awsvpc", + "IPv4Addresses": [ + "10.0.178.177" + ], + "AttachmentIndex": 0, + "MACAddress": "0a:ff:c0:bd:cb:53", + "IPv4SubnetCIDRBlock": "10.0.128.0/17", + "PrivateDNSName": "ip-10-0-178-177.ec2.internal", + "SubnetGatewayIpv4Address": "10.0.128.1/17" + } + ] + }, + { + "DockerId": "b14a1fde2922565d8820e6ee859cdadbc7bc9020c3f751b3446c700deacd1ce8", + "Name": "~internal~ecs~pause", + "DockerName": "ecs-ecs-exporter-fixtures-ec2-4-internalecspause-d0f6aaab84b9e2e8ed01", + "Image": "amazon/amazon-ecs-pause:0.1.0", + "ImageID": "", + "Labels": { + "com.amazonaws.ecs.cluster": "prom-ecs-exporter-fixtures", + "com.amazonaws.ecs.container-name": "~internal~ecs~pause", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb", + "com.amazonaws.ecs.task-definition-family": "ecs-exporter-fixtures-ec2", + "com.amazonaws.ecs.task-definition-version": "4" + }, + "DesiredStatus": "RESOURCES_PROVISIONED", + "KnownStatus": "RESOURCES_PROVISIONED", + "Limits": { + "CPU": 2, + "Memory": 0 + }, + "CreatedAt": "2025-04-28T02:04:55.307033971Z", + "StartedAt": "2025-04-28T02:04:55.775480003Z", + "Type": "CNI_PAUSE", "Networks": [ { - "NetworkMode": "bridge", + "NetworkMode": "awsvpc", "IPv4Addresses": [ - "172.17.0.3" - ] + "10.0.178.177" + ], + "AttachmentIndex": 0, + "MACAddress": "0a:ff:c0:bd:cb:53", + "IPv4SubnetCIDRBlock": "10.0.128.0/17", + "PrivateDNSName": "ip-10-0-178-177.ec2.internal", + "SubnetGatewayIpv4Address": "10.0.128.1/17" } ] } ], - "VPCID": "vpc-0839c743edb0c009e", - "ServiceName": "prom-ecs-exporter-sandbox-main-ec2" + "VPCID": "vpc-033f2f6b3186233ca", + "ServiceName": "prom-ecs-exporter-fixtures-ec2", + "FaultInjectionEnabled": false } diff --git a/ecscollector/testdata/fixtures/ec2_task_stats.json b/ecscollector/testdata/fixtures/ec2_task_stats.json index 4d61c40..0a5b0c8 100644 --- a/ecscollector/testdata/fixtures/ec2_task_stats.json +++ b/ecscollector/testdata/fixtures/ec2_task_stats.json @@ -1,9 +1,10 @@ { - "01cf1f3208005cda71d5ac936ded65d2ecc0a8cc8ff8a82d2e00410bf4fbbd6d": { - "read": "2025-02-27T05:18:07.856950259Z", - "preread": "2025-02-27T05:18:06.853724878Z", + "74d72daf3420705c7038b9f11295b4d951ca32c4f71f1ff6e3abe58202abc093": {}, + "559f4af51a2f85286138de04fbe2892348128ed55dbf24033bc6a1a3eb6f1d7f": { + "read": "2025-04-28T03:30:42.768147457Z", + "preread": "2025-04-28T03:30:41.760208757Z", "pids_stats": { - "current": 33, + "current": 38, "limit": 404 }, "blkio_stats": { @@ -12,13 +13,13 @@ "major": 259, "minor": 0, "op": "read", - "value": 60960768 + "value": 40013824 }, { "major": 259, "minor": 0, "op": "write", - "value": 57344 + "value": 172032 } ], "io_serviced_recursive": null, @@ -33,11 +34,11 @@ "storage_stats": {}, "cpu_stats": { "cpu_usage": { - "total_usage": 331125000, - "usage_in_kernelmode": 66278000, - "usage_in_usermode": 264846000 + "total_usage": 1075472000, + "usage_in_kernelmode": 449300000, + "usage_in_usermode": 626172000 }, - "system_cpu_usage": 1045600000000, + "system_cpu_usage": 10724370000000, "online_cpus": 2, "throttling_data": { "periods": 0, @@ -47,11 +48,11 @@ }, "precpu_stats": { "cpu_usage": { - "total_usage": 325963000, - "usage_in_kernelmode": 65245000, - "usage_in_usermode": 260717000 + "total_usage": 1052847000, + "usage_in_kernelmode": 433699000, + "usage_in_usermode": 619147000 }, - "system_cpu_usage": 1043620000000, + "system_cpu_usage": 10722330000000, "online_cpus": 2, "throttling_data": { "periods": 0, @@ -60,32 +61,32 @@ } }, "memory_stats": { - "usage": 65249280, + "usage": 62619648, "stats": { - "active_anon": 9170944, - "active_file": 7655424, - "anon": 37691392, + "active_anon": 10895360, + "active_file": 13266944, + "anon": 39903232, "anon_thp": 0, - "file": 25296896, - "file_dirty": 4096, - "file_mapped": 19968000, + "file": 20271104, + "file_dirty": 20480, + "file_mapped": 14790656, "file_writeback": 0, - "inactive_anon": 28520448, - "inactive_file": 17641472, - "kernel_stack": 524288, - "pgactivate": 6895, - "pgdeactivate": 4638, - "pgfault": 17631, + "inactive_anon": 29007872, + "inactive_file": 7004160, + "kernel_stack": 606208, + "pgactivate": 6594, + "pgdeactivate": 5012, + "pgfault": 32886, "pglazyfree": 0, "pglazyfreed": 0, - "pgmajfault": 1120, - "pgrefill": 6128, - "pgscan": 24707, - "pgsteal": 10033, + "pgmajfault": 263, + "pgrefill": 6255, + "pgscan": 16825, + "pgsteal": 6574, "shmem": 0, - "slab": 908520, - "slab_reclaimable": 383648, - "slab_unreclaimable": 524872, + "slab": 866488, + "slab_reclaimable": 367352, + "slab_unreclaimable": 499136, "sock": 0, "thp_collapse_alloc": 0, "thp_fault_alloc": 0, @@ -94,33 +95,32 @@ "workingset_nodereclaim": 0, "workingset_refault": 0 }, - "limit": 268435456 + "limit": 134217728 }, - "name": "/ecs-prom-ecs-exporter-sandbox-main-ec2-13-ecs-exporter-e2aeb1e6be8998c72300", - "id": "01cf1f3208005cda71d5ac936ded65d2ecc0a8cc8ff8a82d2e00410bf4fbbd6d", + "name": "/ecs-ecs-exporter-fixtures-ec2-4-ecs-exporter-f8a886e3c3d191f72100", + "id": "559f4af51a2f85286138de04fbe2892348128ed55dbf24033bc6a1a3eb6f1d7f", "networks": { "eth0": { - "rx_bytes": 101869, - "rx_packets": 284, + "rx_bytes": 44555, + "rx_packets": 397, "rx_errors": 0, "rx_dropped": 0, - "tx_bytes": 43958, - "tx_packets": 278, + "tx_bytes": 45918, + "tx_packets": 444, "tx_errors": 0, "tx_dropped": 0 } }, "network_rate_stats": { - "rx_bytes_per_sec": 2764.084716796875, - "tx_bytes_per_sec": 3390.065673828125 + "rx_bytes_per_sec": 4.900143623352051, + "tx_bytes_per_sec": 9.600282669067383 } }, - "213e1203f4bb72af185724d937e698d2724acf35b57ec2dd5f3c963adbd2d38c": {}, - "6b80adab0733f579594eccae31e5b0056b9544b805450ad6e278fed7f5e1c5ba": { - "read": "2025-02-27T05:18:07.855390957Z", - "preread": "2025-02-27T05:18:06.852213453Z", + "b14a1fde2922565d8820e6ee859cdadbc7bc9020c3f751b3446c700deacd1ce8": { + "read": "2025-04-28T03:30:42.765214131Z", + "preread": "2025-04-28T03:30:41.761511112Z", "pids_stats": { - "current": 25, + "current": 1, "limit": 404 }, "blkio_stats": { @@ -129,13 +129,13 @@ "major": 259, "minor": 0, "op": "read", - "value": 99926016 + "value": 770048 }, { "major": 259, "minor": 0, "op": "write", - "value": 274432 + "value": 0 } ], "io_serviced_recursive": null, @@ -150,11 +150,11 @@ "storage_stats": {}, "cpu_stats": { "cpu_usage": { - "total_usage": 566060000, - "usage_in_kernelmode": 164664000, - "usage_in_usermode": 401395000 + "total_usage": 18843000, + "usage_in_kernelmode": 9421000, + "usage_in_usermode": 9421000 }, - "system_cpu_usage": 1045600000000, + "system_cpu_usage": 10724370000000, "online_cpus": 2, "throttling_data": { "periods": 0, @@ -164,11 +164,11 @@ }, "precpu_stats": { "cpu_usage": { - "total_usage": 566060000, - "usage_in_kernelmode": 164664000, - "usage_in_usermode": 401395000 + "total_usage": 18843000, + "usage_in_kernelmode": 9421000, + "usage_in_usermode": 9421000 }, - "system_cpu_usage": 1043620000000, + "system_cpu_usage": 10722330000000, "online_cpus": 2, "throttling_data": { "periods": 0, @@ -177,32 +177,32 @@ } }, "memory_stats": { - "usage": 60981248, + "usage": 655360, "stats": { - "active_anon": 14704640, - "active_file": 8572928, - "anon": 39268352, + "active_anon": 4096, + "active_file": 110592, + "anon": 36864, "anon_thp": 0, - "file": 19619840, + "file": 348160, "file_dirty": 0, - "file_mapped": 17047552, + "file_mapped": 299008, "file_writeback": 0, - "inactive_anon": 24563712, - "inactive_file": 11046912, - "kernel_stack": 393216, - "pgactivate": 13496, - "pgdeactivate": 11069, - "pgfault": 18768, + "inactive_anon": 32768, + "inactive_file": 237568, + "kernel_stack": 16384, + "pgactivate": 3, + "pgdeactivate": 93, + "pgfault": 1086, "pglazyfree": 0, "pglazyfreed": 0, - "pgmajfault": 1133, - "pgrefill": 13249, - "pgscan": 48430, - "pgsteal": 20303, + "pgmajfault": 8, + "pgrefill": 153, + "pgscan": 211, + "pgsteal": 103, "shmem": 0, - "slab": 929280, - "slab_reclaimable": 519208, - "slab_unreclaimable": 410072, + "slab": 201000, + "slab_reclaimable": 72112, + "slab_unreclaimable": 128888, "sock": 0, "thp_collapse_alloc": 0, "thp_fault_alloc": 0, @@ -211,25 +211,141 @@ "workingset_nodereclaim": 0, "workingset_refault": 0 }, - "limit": 268435456 + "limit": 439066624 }, - "name": "/ecs-prom-ecs-exporter-sandbox-main-ec2-13-prometheus-86f1e9bab7a8e9a65400", - "id": "6b80adab0733f579594eccae31e5b0056b9544b805450ad6e278fed7f5e1c5ba", + "name": "/ecs-ecs-exporter-fixtures-ec2-4-internalecspause-d0f6aaab84b9e2e8ed01", + "id": "b14a1fde2922565d8820e6ee859cdadbc7bc9020c3f751b3446c700deacd1ce8", "networks": { "eth0": { - "rx_bytes": 45368, - "rx_packets": 132, + "rx_bytes": 44555, + "rx_packets": 397, "rx_errors": 0, "rx_dropped": 0, - "tx_bytes": 13532, - "tx_packets": 118, + "tx_bytes": 45918, + "tx_packets": 444, "tx_errors": 0, "tx_dropped": 0 } }, "network_rate_stats": { - "rx_bytes_per_sec": 41.86697006225586, - "tx_bytes_per_sec": 41.86697006225586 + "rx_bytes_per_sec": 4.900143623352051, + "tx_bytes_per_sec": 9.600282669067383 + } + }, + "d3b4c06f3fe8614d958ed27f7f3e40adc3b252793399741a92f0935fb60fb5a8": { + "read": "2025-04-28T03:30:42.766822637Z", + "preread": "2025-04-28T03:30:41.76263231Z", + "pids_stats": { + "current": 20, + "limit": 404 + }, + "blkio_stats": { + "io_service_bytes_recursive": [ + { + "major": 259, + "minor": 0, + "op": "read", + "value": 40865792 + }, + { + "major": 259, + "minor": 0, + "op": "write", + "value": 61440 + } + ], + "io_serviced_recursive": null, + "io_queue_recursive": null, + "io_service_time_recursive": null, + "io_wait_time_recursive": null, + "io_merged_recursive": null, + "io_time_recursive": null, + "sectors_recursive": null + }, + "num_procs": 0, + "storage_stats": {}, + "cpu_stats": { + "cpu_usage": { + "total_usage": 639180000, + "usage_in_kernelmode": 192020000, + "usage_in_usermode": 447159000 + }, + "system_cpu_usage": 10724370000000, + "online_cpus": 2, + "throttling_data": { + "periods": 0, + "throttled_periods": 0, + "throttled_time": 0 + } + }, + "precpu_stats": { + "cpu_usage": { + "total_usage": 639180000, + "usage_in_kernelmode": 192020000, + "usage_in_usermode": 447159000 + }, + "system_cpu_usage": 10722330000000, + "online_cpus": 2, + "throttling_data": { + "periods": 0, + "throttled_periods": 0, + "throttled_time": 0 + } + }, + "memory_stats": { + "usage": 26918912, + "stats": { + "active_anon": 7688192, + "active_file": 6758400, + "anon": 15392768, + "anon_thp": 0, + "file": 10203136, + "file_dirty": 0, + "file_mapped": 8835072, + "file_writeback": 0, + "inactive_anon": 7704576, + "inactive_file": 3444736, + "kernel_stack": 311296, + "pgactivate": 5608, + "pgdeactivate": 8637, + "pgfault": 12909, + "pglazyfree": 0, + "pglazyfreed": 0, + "pgmajfault": 1287, + "pgrefill": 17877, + "pgscan": 20826, + "pgsteal": 9626, + "shmem": 0, + "slab": 508584, + "slab_reclaimable": 232736, + "slab_unreclaimable": 275848, + "sock": 0, + "thp_collapse_alloc": 0, + "thp_fault_alloc": 0, + "unevictable": 0, + "workingset_activate": 0, + "workingset_nodereclaim": 0, + "workingset_refault": 0 + }, + "limit": 439066624 + }, + "name": "/ecs-ecs-exporter-fixtures-ec2-4-main-c0d28ea4b8e4b68e2500", + "id": "d3b4c06f3fe8614d958ed27f7f3e40adc3b252793399741a92f0935fb60fb5a8", + "networks": { + "eth0": { + "rx_bytes": 44555, + "rx_packets": 397, + "rx_errors": 0, + "rx_dropped": 0, + "tx_bytes": 45918, + "tx_packets": 444, + "tx_errors": 0, + "tx_dropped": 0 + } + }, + "network_rate_stats": { + "rx_bytes_per_sec": 4.900143623352051, + "tx_bytes_per_sec": 9.600282669067383 } } } diff --git a/ecscollector/testdata/fixtures/fargate_task_metadata.json b/ecscollector/testdata/fixtures/fargate_task_metadata.json index f22c715..766322d 100644 --- a/ecscollector/testdata/fixtures/fargate_task_metadata.json +++ b/ecscollector/testdata/fixtures/fargate_task_metadata.json @@ -1,176 +1,161 @@ { - "Cluster": "arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-sandbox", - "TaskARN": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/bae32def0ab64f06818e8862e58f8d6d", - "Family": "prom-ecs-exporter-sandbox-main-fargate", - "Revision": "9", + "Cluster": "arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-fixtures", + "TaskARN": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/04d558ed038d41bb9de115aab248e4f9", + "Family": "ecs-exporter-fixtures-fargate", + "Revision": "4", "DesiredStatus": "RUNNING", "KnownStatus": "RUNNING", "Limits": { "CPU": 0.25, "Memory": 512 }, - "PullStartedAt": "2025-02-27T05:06:03.714437592Z", - "PullStoppedAt": "2025-02-27T05:06:18.599126545Z", + "PullStartedAt": "2025-04-28T02:04:12.179992648Z", + "PullStoppedAt": "2025-04-28T02:04:21.603777413Z", "AvailabilityZone": "us-east-1a", "LaunchType": "FARGATE", "Containers": [ { - "DockerId": "bae32def0ab64f06818e8862e58f8d6d-1585788040", - "Name": "nonessential", - "DockerName": "nonessential", - "Image": "alpine", - "ImageID": "sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c", + "DockerId": "04d558ed038d41bb9de115aab248e4f9-4159844948", + "Name": "ecs-exporter", + "DockerName": "ecs-exporter", + "Image": "quay.io/prometheuscommunity/ecs-exporter:v0.4.0", + "ImageID": "sha256:e9520794c877d81fec970f2de4558dc0c6e3ac3fd9edf9e4418f326f52236bfb", "Labels": { - "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-sandbox", - "com.amazonaws.ecs.container-name": "nonessential", - "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/bae32def0ab64f06818e8862e58f8d6d", - "com.amazonaws.ecs.task-definition-family": "prom-ecs-exporter-sandbox-main-fargate", - "com.amazonaws.ecs.task-definition-version": "9" + "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-fixtures", + "com.amazonaws.ecs.container-name": "ecs-exporter", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/04d558ed038d41bb9de115aab248e4f9", + "com.amazonaws.ecs.task-definition-family": "ecs-exporter-fixtures-fargate", + "com.amazonaws.ecs.task-definition-version": "4" }, "DesiredStatus": "RUNNING", - "KnownStatus": "STOPPED", - "ExitCode": 0, + "KnownStatus": "RUNNING", "Limits": { - "CPU": 2 + "CPU": 128, + "Memory": 128 }, - "CreatedAt": "2025-02-27T05:06:19.200809191Z", - "StartedAt": "2025-02-27T05:06:19.200809191Z", - "FinishedAt": "2025-02-27T05:06:19.219711004Z", + "CreatedAt": "2025-04-28T02:04:22.237215942Z", + "StartedAt": "2025-04-28T02:04:22.237215942Z", "Type": "NORMAL", - "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-sandbox/bae32def0ab64f06818e8862e58f8d6d/cafd106c-dc95-4396-a466-a894961efa50", + "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-fixtures/04d558ed038d41bb9de115aab248e4f9/9b57fc5b-593c-4e68-ab02-04ae2748e68c", "Networks": [ { "NetworkMode": "awsvpc", "IPv4Addresses": [ - "10.0.117.145" - ], - "IPv6Addresses": [ - "2600:1f18:4ae8:400:7ca9:f2:a4c:8285" + "10.0.170.149" ], "AttachmentIndex": 0, - "MACAddress": "0a:ff:e5:34:fa:c9", - "IPv4SubnetCIDRBlock": "10.0.0.0/17", - "IPv6SubnetCIDRBlock": "2600:1f18:4ae8:400::/64", + "MACAddress": "0a:ff:dd:53:8c:35", + "IPv4SubnetCIDRBlock": "10.0.128.0/17", "DomainNameServers": [ "10.0.0.2" ], "DomainNameSearchList": [ "ec2.internal" ], - "PrivateDNSName": "ip-10-0-117-145.ec2.internal", - "SubnetGatewayIpv4Address": "10.0.0.1/17" + "PrivateDNSName": "ip-10-0-170-149.ec2.internal", + "SubnetGatewayIpv4Address": "10.0.128.1/17" } ], "Snapshotter": "overlayfs" }, { - "DockerId": "bae32def0ab64f06818e8862e58f8d6d-1819985369", - "Name": "prometheus", - "DockerName": "prometheus", - "Image": "prom/prometheus:v3.1.0", - "ImageID": "sha256:6559acbd5d770b15bb3c954629ce190ac3cbbdb2b7f1c30f0385c4e05104e218", + "DockerId": "04d558ed038d41bb9de115aab248e4f9-3935363592", + "Name": "main", + "DockerName": "main", + "Image": "alpine", + "ImageID": "sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c", "Labels": { - "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-sandbox", - "com.amazonaws.ecs.container-name": "prometheus", - "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/bae32def0ab64f06818e8862e58f8d6d", - "com.amazonaws.ecs.task-definition-family": "prom-ecs-exporter-sandbox-main-fargate", - "com.amazonaws.ecs.task-definition-version": "9" + "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-fixtures", + "com.amazonaws.ecs.container-name": "main", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/04d558ed038d41bb9de115aab248e4f9", + "com.amazonaws.ecs.task-definition-family": "ecs-exporter-fixtures-fargate", + "com.amazonaws.ecs.task-definition-version": "4" }, "DesiredStatus": "RUNNING", "KnownStatus": "RUNNING", "Limits": { "CPU": 2 }, - "CreatedAt": "2025-02-27T05:06:19.179996393Z", - "StartedAt": "2025-02-27T05:06:19.179996393Z", + "CreatedAt": "2025-04-28T02:04:22.279743113Z", + "StartedAt": "2025-04-28T02:04:22.279743113Z", "Type": "NORMAL", - "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-sandbox/bae32def0ab64f06818e8862e58f8d6d/50e269e1-4232-4aed-8bf4-29c4909858f9", + "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-fixtures/04d558ed038d41bb9de115aab248e4f9/ec4f2206-b03b-49e8-bcd7-dcf6b962d021", "Networks": [ { "NetworkMode": "awsvpc", "IPv4Addresses": [ - "10.0.117.145" - ], - "IPv6Addresses": [ - "2600:1f18:4ae8:400:7ca9:f2:a4c:8285" + "10.0.170.149" ], "AttachmentIndex": 0, - "MACAddress": "0a:ff:e5:34:fa:c9", - "IPv4SubnetCIDRBlock": "10.0.0.0/17", - "IPv6SubnetCIDRBlock": "2600:1f18:4ae8:400::/64", + "MACAddress": "0a:ff:dd:53:8c:35", + "IPv4SubnetCIDRBlock": "10.0.128.0/17", "DomainNameServers": [ "10.0.0.2" ], "DomainNameSearchList": [ "ec2.internal" ], - "PrivateDNSName": "ip-10-0-117-145.ec2.internal", - "SubnetGatewayIpv4Address": "10.0.0.1/17" + "PrivateDNSName": "ip-10-0-170-149.ec2.internal", + "SubnetGatewayIpv4Address": "10.0.128.1/17" } ], "Snapshotter": "overlayfs" }, { - "DockerId": "bae32def0ab64f06818e8862e58f8d6d-4159844948", - "Name": "ecs-exporter", - "DockerName": "ecs-exporter", - "Image": "quay.io/prometheuscommunity/ecs-exporter:main", - "ImageID": "sha256:d1802fb18cb208eda88d4b23aeff903e72c091c20fcdf02596d6bec4679f676d", + "DockerId": "04d558ed038d41bb9de115aab248e4f9-1585788040", + "Name": "nonessential", + "DockerName": "nonessential", + "Image": "alpine", + "ImageID": "sha256:a8560b36e8b8210634f77d9f7f9efd7ffa463e380b75e2e74aff4511df3ef88c", "Labels": { - "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-sandbox", - "com.amazonaws.ecs.container-name": "ecs-exporter", - "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/bae32def0ab64f06818e8862e58f8d6d", - "com.amazonaws.ecs.task-definition-family": "prom-ecs-exporter-sandbox-main-fargate", - "com.amazonaws.ecs.task-definition-version": "9" + "com.amazonaws.ecs.cluster": "arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-fixtures", + "com.amazonaws.ecs.container-name": "nonessential", + "com.amazonaws.ecs.task-arn": "arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/04d558ed038d41bb9de115aab248e4f9", + "com.amazonaws.ecs.task-definition-family": "ecs-exporter-fixtures-fargate", + "com.amazonaws.ecs.task-definition-version": "4" }, "DesiredStatus": "RUNNING", - "KnownStatus": "RUNNING", + "KnownStatus": "STOPPED", + "ExitCode": 0, "Limits": { - "CPU": 2 + "CPU": 128, + "Memory": 128 }, - "CreatedAt": "2025-02-27T05:06:19.394790335Z", - "StartedAt": "2025-02-27T05:06:19.394790335Z", + "CreatedAt": "2025-04-28T02:04:22.240922754Z", + "StartedAt": "2025-04-28T02:04:22.240922754Z", + "FinishedAt": "2025-04-28T02:04:22.270452337Z", "Type": "NORMAL", - "LogDriver": "awslogs", - "LogOptions": { - "awslogs-group": "EcsExporterCdkStack-promecsexportersandboxmainfargatetaskdefinitionpromecsexportersandboxmainfargateecsexporterLogGroup44D32D35-DcG8HDbOu1Sl", - "awslogs-region": "us-east-1", - "awslogs-stream": "ecs-exporter/ecs-exporter/bae32def0ab64f06818e8862e58f8d6d" - }, - "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-sandbox/bae32def0ab64f06818e8862e58f8d6d/a9b9d903-4ca1-4ce2-8138-93094e438c6b", + "ContainerARN": "arn:aws:ecs:us-east-1:829490980523:container/prom-ecs-exporter-fixtures/04d558ed038d41bb9de115aab248e4f9/5c195179-a14d-422e-9c85-bbee7bbbfc44", "Networks": [ { "NetworkMode": "awsvpc", "IPv4Addresses": [ - "10.0.117.145" - ], - "IPv6Addresses": [ - "2600:1f18:4ae8:400:7ca9:f2:a4c:8285" + "10.0.170.149" ], "AttachmentIndex": 0, - "MACAddress": "0a:ff:e5:34:fa:c9", - "IPv4SubnetCIDRBlock": "10.0.0.0/17", - "IPv6SubnetCIDRBlock": "2600:1f18:4ae8:400::/64", + "MACAddress": "0a:ff:dd:53:8c:35", + "IPv4SubnetCIDRBlock": "10.0.128.0/17", "DomainNameServers": [ "10.0.0.2" ], "DomainNameSearchList": [ "ec2.internal" ], - "PrivateDNSName": "ip-10-0-117-145.ec2.internal", - "SubnetGatewayIpv4Address": "10.0.0.1/17" + "PrivateDNSName": "ip-10-0-170-149.ec2.internal", + "SubnetGatewayIpv4Address": "10.0.128.1/17" } ], "Snapshotter": "overlayfs" } ], "ClockDrift": { - "ClockErrorBound": 0.33292849999999996, - "ReferenceTimestamp": "2025-02-27T05:22:43Z", + "ClockErrorBound": 0.6756489999999999, + "ReferenceTimestamp": "2025-04-28T03:30:17Z", "ClockSynchronizationStatus": "SYNCHRONIZED" }, "EphemeralStorageMetrics": { - "Utilized": 427, + "Utilized": 40, "Reserved": 20496 - } + }, + "FaultInjectionEnabled": false } diff --git a/ecscollector/testdata/fixtures/fargate_task_stats.json b/ecscollector/testdata/fixtures/fargate_task_stats.json index 8892403..6761192 100644 --- a/ecscollector/testdata/fixtures/fargate_task_stats.json +++ b/ecscollector/testdata/fixtures/fargate_task_stats.json @@ -1,8 +1,8 @@ { - "bae32def0ab64f06818e8862e58f8d6d-1585788040": null, - "bae32def0ab64f06818e8862e58f8d6d-1819985369": { - "read": "2025-02-27T05:22:49.186680233Z", - "preread": "2025-02-27T05:22:39.185738849Z", + "04d558ed038d41bb9de115aab248e4f9-1585788040": null, + "04d558ed038d41bb9de115aab248e4f9-4159844948": { + "read": "2025-04-28T03:30:22.254837493Z", + "preread": "2025-04-28T03:30:12.255515507Z", "pids_stats": {}, "blkio_stats": { "io_service_bytes_recursive": [ @@ -10,25 +10,25 @@ "major": 259, "minor": 1, "op": "Read", - "value": 23793664 + "value": 12288 }, { "major": 259, "minor": 1, "op": "Write", - "value": 0 + "value": 172032 }, { "major": 259, "minor": 1, "op": "Sync", - "value": 23793664 + "value": 12288 }, { "major": 259, "minor": 1, "op": "Async", - "value": 0 + "value": 172032 }, { "major": 259, @@ -40,13 +40,13 @@ "major": 259, "minor": 1, "op": "Total", - "value": 23793664 + "value": 184320 }, { "major": 259, "minor": 0, "op": "Read", - "value": 65409024 + "value": 10608640 }, { "major": 259, @@ -58,7 +58,7 @@ "major": 259, "minor": 0, "op": "Sync", - "value": 65409024 + "value": 10608640 }, { "major": 259, @@ -76,7 +76,7 @@ "major": 259, "minor": 0, "op": "Total", - "value": 65409024 + "value": 10608640 } ], "io_serviced_recursive": [ @@ -84,25 +84,25 @@ "major": 259, "minor": 1, "op": "Read", - "value": 295 + "value": 3 }, { "major": 259, "minor": 1, "op": "Write", - "value": 0 + "value": 42 }, { "major": 259, "minor": 1, "op": "Sync", - "value": 295 + "value": 3 }, { "major": 259, "minor": 1, "op": "Async", - "value": 0 + "value": 42 }, { "major": 259, @@ -114,13 +114,13 @@ "major": 259, "minor": 1, "op": "Total", - "value": 295 + "value": 45 }, { "major": 259, "minor": 0, "op": "Read", - "value": 682 + "value": 118 }, { "major": 259, @@ -132,7 +132,7 @@ "major": 259, "minor": 0, "op": "Sync", - "value": 682 + "value": 118 }, { "major": 259, @@ -150,7 +150,7 @@ "major": 259, "minor": 0, "op": "Total", - "value": 682 + "value": 118 } ], "io_queue_recursive": [], @@ -164,15 +164,15 @@ "storage_stats": {}, "cpu_stats": { "cpu_usage": { - "total_usage": 932439492, + "total_usage": 2445096927, "percpu_usage": [ - 484165457, - 448274035 + 1217444718, + 1227652209 ], - "usage_in_kernelmode": 120000000, - "usage_in_usermode": 880000000 + "usage_in_kernelmode": 750000000, + "usage_in_usermode": 1400000000 }, - "system_cpu_usage": 2121200000000, + "system_cpu_usage": 10690100000000, "online_cpus": 2, "throttling_data": { "periods": 0, @@ -182,15 +182,15 @@ }, "precpu_stats": { "cpu_usage": { - "total_usage": 925246189, + "total_usage": 2405275582, "percpu_usage": [ - 479268399, - 445977790 + 1199980331, + 1205295251 ], - "usage_in_kernelmode": 120000000, - "usage_in_usermode": 870000000 + "usage_in_kernelmode": 720000000, + "usage_in_usermode": 1390000000 }, - "system_cpu_usage": 2101320000000, + "system_cpu_usage": 10670160000000, "online_cpus": 2, "throttling_data": { "periods": 0, @@ -199,66 +199,66 @@ } }, "memory_stats": { - "usage": 127934464, - "max_usage": 128557056, + "usage": 40611840, + "max_usage": 69406720, "stats": { "active_anon": 0, - "active_file": 32952320, - "cache": 85426176, - "dirty": 0, - "hierarchical_memory_limit": 536870912, + "active_file": 10346496, + "cache": 11218944, + "dirty": 135168, + "hierarchical_memory_limit": 134217728, "hierarchical_memsw_limit": 9223372036854771712, - "inactive_anon": 40820736, - "inactive_file": 52383744, - "mapped_file": 72179712, - "pgfault": 18975, - "pgmajfault": 693, - "pgpgin": 34749, - "pgpgout": 3936, - "rss": 40820736, + "inactive_anon": 27844608, + "inactive_file": 946176, + "mapped_file": 8110080, + "pgfault": 108042, + "pgmajfault": 33, + "pgpgin": 88473, + "pgpgout": 78973, + "rss": 27844608, "rss_huge": 0, "total_active_anon": 0, - "total_active_file": 32952320, - "total_cache": 85426176, - "total_dirty": 0, - "total_inactive_anon": 40820736, - "total_inactive_file": 52383744, - "total_mapped_file": 72179712, - "total_pgfault": 18975, - "total_pgmajfault": 693, - "total_pgpgin": 34749, - "total_pgpgout": 3936, - "total_rss": 40820736, + "total_active_file": 10346496, + "total_cache": 11218944, + "total_dirty": 135168, + "total_inactive_anon": 27844608, + "total_inactive_file": 946176, + "total_mapped_file": 8110080, + "total_pgfault": 108042, + "total_pgmajfault": 33, + "total_pgpgin": 88473, + "total_pgpgout": 78973, + "total_rss": 27844608, "total_rss_huge": 0, "total_unevictable": 0, "total_writeback": 0, "unevictable": 0, "writeback": 0 }, - "limit": 9223372036854771712 + "limit": 134217728 }, - "name": "prometheus", - "id": "bae32def0ab64f06818e8862e58f8d6d-1819985369", + "name": "ecs-exporter", + "id": "04d558ed038d41bb9de115aab248e4f9-4159844948", "networks": { "eth1": { - "rx_bytes": 129045374, - "rx_packets": 88933, + "rx_bytes": 12906990, + "rx_packets": 10768, "rx_errors": 0, "rx_dropped": 0, - "tx_bytes": 347839, - "tx_packets": 3501, + "tx_bytes": 462136, + "tx_packets": 2956, "tx_errors": 0, "tx_dropped": 0 } }, "network_rate_stats": { - "rx_bytes_per_sec": 2464.6679803462657, - "tx_bytes_per_sec": 1173.289548516495 + "rx_bytes_per_sec": 1239.9840756322674, + "tx_bytes_per_sec": 1673.6134773534957 } }, - "bae32def0ab64f06818e8862e58f8d6d-4159844948": { - "read": "2025-02-27T05:22:49.406170373Z", - "preread": "2025-02-27T05:22:39.406479661Z", + "04d558ed038d41bb9de115aab248e4f9-3935363592": { + "read": "2025-04-28T03:30:22.287279291Z", + "preread": "2025-04-28T03:30:12.286947751Z", "pids_stats": {}, "blkio_stats": { "io_service_bytes_recursive": [ @@ -266,7 +266,7 @@ "major": 259, "minor": 1, "op": "Read", - "value": 28639232 + "value": 1576960 }, { "major": 259, @@ -278,7 +278,7 @@ "major": 259, "minor": 1, "op": "Sync", - "value": 28639232 + "value": 1576960 }, { "major": 259, @@ -296,31 +296,31 @@ "major": 259, "minor": 1, "op": "Total", - "value": 28639232 + "value": 1576960 }, { "major": 259, "minor": 0, "op": "Read", - "value": 14655488 + "value": 2088960 }, { "major": 259, "minor": 0, "op": "Write", - "value": 4096 + "value": 0 }, { "major": 259, "minor": 0, "op": "Sync", - "value": 14655488 + "value": 2088960 }, { "major": 259, "minor": 0, "op": "Async", - "value": 4096 + "value": 0 }, { "major": 259, @@ -332,7 +332,7 @@ "major": 259, "minor": 0, "op": "Total", - "value": 14659584 + "value": 2088960 } ], "io_serviced_recursive": [ @@ -340,7 +340,7 @@ "major": 259, "minor": 1, "op": "Read", - "value": 327 + "value": 37 }, { "major": 259, @@ -352,7 +352,7 @@ "major": 259, "minor": 1, "op": "Sync", - "value": 327 + "value": 37 }, { "major": 259, @@ -370,31 +370,31 @@ "major": 259, "minor": 1, "op": "Total", - "value": 327 + "value": 37 }, { "major": 259, "minor": 0, "op": "Read", - "value": 157 + "value": 31 }, { "major": 259, "minor": 0, "op": "Write", - "value": 1 + "value": 0 }, { "major": 259, "minor": 0, "op": "Sync", - "value": 157 + "value": 31 }, { "major": 259, "minor": 0, "op": "Async", - "value": 1 + "value": 0 }, { "major": 259, @@ -406,7 +406,7 @@ "major": 259, "minor": 0, "op": "Total", - "value": 158 + "value": 31 } ], "io_queue_recursive": [], @@ -420,15 +420,15 @@ "storage_stats": {}, "cpu_stats": { "cpu_usage": { - "total_usage": 322633383, + "total_usage": 609984441, "percpu_usage": [ - 138347736, - 184285647 + 334299398, + 275685043 ], - "usage_in_kernelmode": 50000000, - "usage_in_usermode": 180000000 + "usage_in_kernelmode": 80000000, + "usage_in_usermode": 370000000 }, - "system_cpu_usage": 2121630000000, + "system_cpu_usage": 10690160000000, "online_cpus": 2, "throttling_data": { "periods": 0, @@ -438,15 +438,15 @@ }, "precpu_stats": { "cpu_usage": { - "total_usage": 242770940, + "total_usage": 609984441, "percpu_usage": [ - 104627034, - 138143906 + 334299398, + 275685043 ], - "usage_in_kernelmode": 30000000, - "usage_in_usermode": 140000000 + "usage_in_kernelmode": 80000000, + "usage_in_usermode": 370000000 }, - "system_cpu_usage": 2101780000000, + "system_cpu_usage": 10670220000000, "online_cpus": 2, "throttling_data": { "periods": 0, @@ -455,36 +455,36 @@ } }, "memory_stats": { - "usage": 84111360, - "max_usage": 84238336, + "usage": 24264704, + "max_usage": 27025408, "stats": { "active_anon": 0, - "active_file": 3379200, - "cache": 42442752, + "active_file": 3649536, + "cache": 3649536, "dirty": 0, "hierarchical_memory_limit": 536870912, "hierarchical_memsw_limit": 9223372036854771712, - "inactive_anon": 39469056, - "inactive_file": 39100416, - "mapped_file": 33927168, - "pgfault": 17358, - "pgmajfault": 297, - "pgpgin": 23430, - "pgpgout": 3367, - "rss": 39469056, + "inactive_anon": 19193856, + "inactive_file": 270336, + "mapped_file": 1757184, + "pgfault": 12078, + "pgmajfault": 0, + "pgpgin": 9306, + "pgpgout": 3671, + "rss": 19329024, "rss_huge": 0, "total_active_anon": 0, - "total_active_file": 3379200, - "total_cache": 42442752, + "total_active_file": 3649536, + "total_cache": 3649536, "total_dirty": 0, - "total_inactive_anon": 39469056, - "total_inactive_file": 39100416, - "total_mapped_file": 33927168, - "total_pgfault": 17358, - "total_pgmajfault": 297, - "total_pgpgin": 23430, - "total_pgpgout": 3367, - "total_rss": 39469056, + "total_inactive_anon": 19193856, + "total_inactive_file": 270336, + "total_mapped_file": 1757184, + "total_pgfault": 12078, + "total_pgmajfault": 0, + "total_pgpgin": 9306, + "total_pgpgout": 3671, + "total_rss": 19329024, "total_rss_huge": 0, "total_unevictable": 0, "total_writeback": 0, @@ -493,23 +493,23 @@ }, "limit": 9223372036854771712 }, - "name": "ecs-exporter", - "id": "bae32def0ab64f06818e8862e58f8d6d-4159844948", + "name": "main", + "id": "04d558ed038d41bb9de115aab248e4f9-3935363592", "networks": { "eth1": { - "rx_bytes": 129046293, - "rx_packets": 88938, + "rx_bytes": 12906990, + "rx_packets": 10768, "rx_errors": 0, "rx_dropped": 0, - "tx_bytes": 348223, - "tx_packets": 3507, + "tx_bytes": 462136, + "tx_packets": 2956, "tx_errors": 0, "tx_dropped": 0 } }, "network_rate_stats": { - "rx_bytes_per_sec": 2556.879064581499, - "tx_bytes_per_sec": 1211.8374728018853 + "rx_bytes_per_sec": 1187.660623349565, + "tx_bytes_per_sec": 1666.8447360961436 } } } diff --git a/ecscollector/testdata/snapshots/ec2_metrics.txt b/ecscollector/testdata/snapshots/ec2_metrics.txt index 7674fff..79f5062 100644 --- a/ecscollector/testdata/snapshots/ec2_metrics.txt +++ b/ecscollector/testdata/snapshots/ec2_metrics.txt @@ -1,22 +1,26 @@ # HELP ecs_container_cpu_usage_seconds_total Cumulative total container CPU usage in seconds. # TYPE ecs_container_cpu_usage_seconds_total counter -ecs_container_cpu_usage_seconds_total{container_name="ecs-exporter"} 0.331125 -ecs_container_cpu_usage_seconds_total{container_name="prometheus"} 0.56606 +ecs_container_cpu_usage_seconds_total{container_name="ecs-exporter"} 1.075472 +ecs_container_cpu_usage_seconds_total{container_name="main"} 0.6391800000000001 +ecs_container_cpu_usage_seconds_total{container_name="~internal~ecs~pause"} 0.018843000000000002 # HELP ecs_container_memory_limit_bytes Configured container memory limit in bytes, set from the container-level limit in the task definition if any, otherwise the task-level limit. # TYPE ecs_container_memory_limit_bytes gauge -ecs_container_memory_limit_bytes{container_name="ecs-exporter"} 2.68435456e+08 -ecs_container_memory_limit_bytes{container_name="prometheus"} 2.68435456e+08 +ecs_container_memory_limit_bytes{container_name="ecs-exporter"} 1.34217728e+08 +ecs_container_memory_limit_bytes{container_name="main"} 0 +ecs_container_memory_limit_bytes{container_name="~internal~ecs~pause"} 0 # HELP ecs_container_memory_page_cache_size_bytes Current container memory page cache size in bytes. This is not a subset of used bytes. # TYPE ecs_container_memory_page_cache_size_bytes gauge ecs_container_memory_page_cache_size_bytes{container_name="ecs-exporter"} 0 -ecs_container_memory_page_cache_size_bytes{container_name="prometheus"} 0 +ecs_container_memory_page_cache_size_bytes{container_name="main"} 0 +ecs_container_memory_page_cache_size_bytes{container_name="~internal~ecs~pause"} 0 # HELP ecs_container_memory_usage_bytes Current container memory usage in bytes. # TYPE ecs_container_memory_usage_bytes gauge -ecs_container_memory_usage_bytes{container_name="ecs-exporter"} 6.524928e+07 -ecs_container_memory_usage_bytes{container_name="prometheus"} 6.0981248e+07 +ecs_container_memory_usage_bytes{container_name="ecs-exporter"} 6.2619648e+07 +ecs_container_memory_usage_bytes{container_name="main"} 2.6918912e+07 +ecs_container_memory_usage_bytes{container_name="~internal~ecs~pause"} 655360 # HELP ecs_network_receive_bytes_total Cumulative total size of network packets received in bytes. # TYPE ecs_network_receive_bytes_total counter -ecs_network_receive_bytes_total{interface="eth0"} 45368 +ecs_network_receive_bytes_total{interface="eth0"} 44555 # HELP ecs_network_receive_errors_total Cumulative total count of network errors in receiving. # TYPE ecs_network_receive_errors_total counter ecs_network_receive_errors_total{interface="eth0"} 0 @@ -25,10 +29,10 @@ ecs_network_receive_errors_total{interface="eth0"} 0 ecs_network_receive_packets_dropped_total{interface="eth0"} 0 # HELP ecs_network_receive_packets_total Cumulative total count of network packets received. # TYPE ecs_network_receive_packets_total counter -ecs_network_receive_packets_total{interface="eth0"} 132 +ecs_network_receive_packets_total{interface="eth0"} 397 # HELP ecs_network_transmit_bytes_total Cumulative total size of network packets transmitted in bytes. # TYPE ecs_network_transmit_bytes_total counter -ecs_network_transmit_bytes_total{interface="eth0"} 13532 +ecs_network_transmit_bytes_total{interface="eth0"} 45918 # HELP ecs_network_transmit_errors_total Cumulative total count of network errors in transmit. # TYPE ecs_network_transmit_errors_total counter ecs_network_transmit_errors_total{interface="eth0"} 0 @@ -37,13 +41,16 @@ ecs_network_transmit_errors_total{interface="eth0"} 0 ecs_network_transmit_packets_dropped_total{interface="eth0"} 0 # HELP ecs_network_transmit_packets_total Cumulative total count of network packets transmitted. # TYPE ecs_network_transmit_packets_total counter -ecs_network_transmit_packets_total{interface="eth0"} 118 +ecs_network_transmit_packets_total{interface="eth0"} 444 # HELP ecs_task_image_pull_start_timestamp_seconds The time at which the task started pulling docker images for its containers. # TYPE ecs_task_image_pull_start_timestamp_seconds gauge -ecs_task_image_pull_start_timestamp_seconds 1.7406329923325953e+09 +ecs_task_image_pull_start_timestamp_seconds 1.7458058962032692e+09 # HELP ecs_task_image_pull_stop_timestamp_seconds The time at which the task stopped (i.e. completed) pulling docker images for its containers. # TYPE ecs_task_image_pull_stop_timestamp_seconds gauge -ecs_task_image_pull_stop_timestamp_seconds 1.7406330012060723e+09 +ecs_task_image_pull_stop_timestamp_seconds 1.7458059035167944e+09 +# HELP ecs_task_memory_limit_bytes Configured task memory limit in bytes. This is optional when running on EC2; if no limit is set, this metric has no value. +# TYPE ecs_task_memory_limit_bytes gauge +ecs_task_memory_limit_bytes 2.68435456e+08 # HELP ecs_task_metadata_info ECS task metadata, sourced from the task metadata endpoint version 4. # TYPE ecs_task_metadata_info gauge -ecs_task_metadata_info{availability_zone="us-east-1a",cluster="prom-ecs-exporter-sandbox",desired_status="RUNNING",family="prom-ecs-exporter-sandbox-main-ec2",known_status="RUNNING",launch_type="EC2",revision="13",task_arn="arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/506f22fab0414cde856201584703fed9"} 1 +ecs_task_metadata_info{availability_zone="us-east-1a",cluster="prom-ecs-exporter-fixtures",desired_status="RUNNING",family="ecs-exporter-fixtures-ec2",known_status="RUNNING",launch_type="EC2",revision="4",task_arn="arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/1e76d951e76c4ea5ad410966ffde3bdb"} 1 diff --git a/ecscollector/testdata/snapshots/fargate_metrics.txt b/ecscollector/testdata/snapshots/fargate_metrics.txt index 83cf0f0..168a8ad 100644 --- a/ecscollector/testdata/snapshots/fargate_metrics.txt +++ b/ecscollector/testdata/snapshots/fargate_metrics.txt @@ -1,22 +1,22 @@ # HELP ecs_container_cpu_usage_seconds_total Cumulative total container CPU usage in seconds. # TYPE ecs_container_cpu_usage_seconds_total counter -ecs_container_cpu_usage_seconds_total{container_name="ecs-exporter"} 0.322633383 -ecs_container_cpu_usage_seconds_total{container_name="prometheus"} 0.9324394920000001 +ecs_container_cpu_usage_seconds_total{container_name="ecs-exporter"} 2.4450969270000003 +ecs_container_cpu_usage_seconds_total{container_name="main"} 0.609984441 # HELP ecs_container_memory_limit_bytes Configured container memory limit in bytes, set from the container-level limit in the task definition if any, otherwise the task-level limit. # TYPE ecs_container_memory_limit_bytes gauge -ecs_container_memory_limit_bytes{container_name="ecs-exporter"} 5.36870912e+08 -ecs_container_memory_limit_bytes{container_name="prometheus"} 5.36870912e+08 +ecs_container_memory_limit_bytes{container_name="ecs-exporter"} 1.34217728e+08 +ecs_container_memory_limit_bytes{container_name="main"} 5.36870912e+08 # HELP ecs_container_memory_page_cache_size_bytes Current container memory page cache size in bytes. This is not a subset of used bytes. # TYPE ecs_container_memory_page_cache_size_bytes gauge -ecs_container_memory_page_cache_size_bytes{container_name="ecs-exporter"} 4.2442752e+07 -ecs_container_memory_page_cache_size_bytes{container_name="prometheus"} 8.5426176e+07 +ecs_container_memory_page_cache_size_bytes{container_name="ecs-exporter"} 1.1218944e+07 +ecs_container_memory_page_cache_size_bytes{container_name="main"} 3.649536e+06 # HELP ecs_container_memory_usage_bytes Current container memory usage in bytes. # TYPE ecs_container_memory_usage_bytes gauge -ecs_container_memory_usage_bytes{container_name="ecs-exporter"} 8.411136e+07 -ecs_container_memory_usage_bytes{container_name="prometheus"} 1.27934464e+08 +ecs_container_memory_usage_bytes{container_name="ecs-exporter"} 4.061184e+07 +ecs_container_memory_usage_bytes{container_name="main"} 2.4264704e+07 # HELP ecs_network_receive_bytes_total Cumulative total size of network packets received in bytes. # TYPE ecs_network_receive_bytes_total counter -ecs_network_receive_bytes_total{interface="eth1"} 1.29046293e+08 +ecs_network_receive_bytes_total{interface="eth1"} 1.290699e+07 # HELP ecs_network_receive_errors_total Cumulative total count of network errors in receiving. # TYPE ecs_network_receive_errors_total counter ecs_network_receive_errors_total{interface="eth1"} 0 @@ -25,10 +25,10 @@ ecs_network_receive_errors_total{interface="eth1"} 0 ecs_network_receive_packets_dropped_total{interface="eth1"} 0 # HELP ecs_network_receive_packets_total Cumulative total count of network packets received. # TYPE ecs_network_receive_packets_total counter -ecs_network_receive_packets_total{interface="eth1"} 88938 +ecs_network_receive_packets_total{interface="eth1"} 10768 # HELP ecs_network_transmit_bytes_total Cumulative total size of network packets transmitted in bytes. # TYPE ecs_network_transmit_bytes_total counter -ecs_network_transmit_bytes_total{interface="eth1"} 348223 +ecs_network_transmit_bytes_total{interface="eth1"} 462136 # HELP ecs_network_transmit_errors_total Cumulative total count of network errors in transmit. # TYPE ecs_network_transmit_errors_total counter ecs_network_transmit_errors_total{interface="eth1"} 0 @@ -37,7 +37,7 @@ ecs_network_transmit_errors_total{interface="eth1"} 0 ecs_network_transmit_packets_dropped_total{interface="eth1"} 0 # HELP ecs_network_transmit_packets_total Cumulative total count of network packets transmitted. # TYPE ecs_network_transmit_packets_total counter -ecs_network_transmit_packets_total{interface="eth1"} 3507 +ecs_network_transmit_packets_total{interface="eth1"} 2956 # HELP ecs_task_cpu_limit_vcpus Configured task CPU limit in vCPUs (1 vCPU = 1024 CPU units). This is optional when running on EC2; if no limit is set, this metric has no value. # TYPE ecs_task_cpu_limit_vcpus gauge ecs_task_cpu_limit_vcpus 0.25 @@ -46,16 +46,16 @@ ecs_task_cpu_limit_vcpus 0.25 ecs_task_ephemeral_storage_allocated_bytes 2.1491613696e+10 # HELP ecs_task_ephemeral_storage_used_bytes Current Fargate task ephemeral storage usage in bytes. # TYPE ecs_task_ephemeral_storage_used_bytes gauge -ecs_task_ephemeral_storage_used_bytes 4.47741952e+08 +ecs_task_ephemeral_storage_used_bytes 4.194304e+07 # HELP ecs_task_image_pull_start_timestamp_seconds The time at which the task started pulling docker images for its containers. # TYPE ecs_task_image_pull_start_timestamp_seconds gauge -ecs_task_image_pull_start_timestamp_seconds 1.7406327637144377e+09 +ecs_task_image_pull_start_timestamp_seconds 1.7458058521799927e+09 # HELP ecs_task_image_pull_stop_timestamp_seconds The time at which the task stopped (i.e. completed) pulling docker images for its containers. # TYPE ecs_task_image_pull_stop_timestamp_seconds gauge -ecs_task_image_pull_stop_timestamp_seconds 1.7406327785991266e+09 +ecs_task_image_pull_stop_timestamp_seconds 1.7458058616037776e+09 # HELP ecs_task_memory_limit_bytes Configured task memory limit in bytes. This is optional when running on EC2; if no limit is set, this metric has no value. # TYPE ecs_task_memory_limit_bytes gauge ecs_task_memory_limit_bytes 5.36870912e+08 # HELP ecs_task_metadata_info ECS task metadata, sourced from the task metadata endpoint version 4. # TYPE ecs_task_metadata_info gauge -ecs_task_metadata_info{availability_zone="us-east-1a",cluster="arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-sandbox",desired_status="RUNNING",family="prom-ecs-exporter-sandbox-main-fargate",known_status="RUNNING",launch_type="FARGATE",revision="9",task_arn="arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-sandbox/bae32def0ab64f06818e8862e58f8d6d"} 1 +ecs_task_metadata_info{availability_zone="us-east-1a",cluster="arn:aws:ecs:us-east-1:829490980523:cluster/prom-ecs-exporter-fixtures",desired_status="RUNNING",family="ecs-exporter-fixtures-fargate",known_status="RUNNING",launch_type="FARGATE",revision="4",task_arn="arn:aws:ecs:us-east-1:829490980523:task/prom-ecs-exporter-fixtures/04d558ed038d41bb9de115aab248e4f9"} 1 diff --git a/go.mod b/go.mod index 5d91fcc..77f5139 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,9 @@ go 1.23.0 require ( github.com/alecthomas/kingpin/v2 v2.4.0 github.com/aws/amazon-ecs-agent/ecs-agent v0.0.0-20250311191058-43b89f06b96f + github.com/aws/aws-cdk-go/awscdk/v2 v2.192.0 + github.com/aws/constructs-go/constructs/v10 v10.4.2 + github.com/aws/jsii-runtime-go v1.111.0 github.com/docker/docker v27.3.1+incompatible github.com/prometheus/client_golang v1.21.1 github.com/prometheus/common v0.62.0 @@ -12,20 +15,27 @@ require ( ) require ( + github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/aws/aws-sdk-go v1.51.3 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.229 // indirect + github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.1.0 // indirect + github.com/cdklabs/cloud-assembly-schema-go/awscdkcloudassemblyschema/v41 v41.0.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/fatih/color v1.18.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/klauspost/compress v1.17.11 // indirect github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mdlayher/socket v0.4.1 // indirect github.com/mdlayher/vsock v1.2.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect @@ -39,13 +49,17 @@ require ( github.com/vishvananda/netlink v1.2.1-beta.2 // indirect github.com/vishvananda/netns v0.0.4 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - golang.org/x/crypto v0.31.0 // indirect + github.com/yuin/goldmark v1.4.13 // indirect + golang.org/x/crypto v0.36.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/net v0.33.0 // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect + golang.org/x/mod v0.24.0 // indirect + golang.org/x/net v0.37.0 // indirect golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/tools v0.31.0 // indirect google.golang.org/protobuf v1.36.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 3001c0f..30efefd 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,27 @@ +github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= +github.com/Masterminds/semver/v3 v3.3.1/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY= github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/aws/amazon-ecs-agent/ecs-agent v0.0.0-20250311191058-43b89f06b96f h1:DJrZ85TxEVYi6K2Ao1UCzI98oyFzu2XpmpSjiHtmV8Q= github.com/aws/amazon-ecs-agent/ecs-agent v0.0.0-20250311191058-43b89f06b96f/go.mod h1:Myn1TSfJvFHEftmqtT3aw4CYktyuLijgKw8LOteQLno= +github.com/aws/aws-cdk-go/awscdk/v2 v2.192.0 h1:HYswn2veBK2NdL5NrH6rbCaBKLZKwj1q0SVsGcOziYk= +github.com/aws/aws-cdk-go/awscdk/v2 v2.192.0/go.mod h1:9ENCp/SkuTkIrAxG0cEdAD1QCC+QfpN82ukwrbwzwGE= github.com/aws/aws-sdk-go v1.51.3 h1:OqSyEXcJwf/XhZNVpMRgKlLA9nmbo5X8dwbll4RWxq8= github.com/aws/aws-sdk-go v1.51.3/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/constructs-go/constructs/v10 v10.4.2 h1:+hDLTsFGLJmKIn0Dg20vWpKBrVnFrEWYgTEY5UiTEG8= +github.com/aws/constructs-go/constructs/v10 v10.4.2/go.mod h1:cXsNCKDV+9eR9zYYfwy6QuE4uPFp6jsq6TtH1MwBx9w= +github.com/aws/jsii-runtime-go v1.111.0 h1:KR0URQxaw6FRTtNSKQ/weqVP2QEaAOssBcKD/uBlnh4= +github.com/aws/jsii-runtime-go v1.111.0/go.mod h1:eLDUEd0lRYsu2WoR+EoApYPz6ibG7JOaJgbL0IlD/m8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.229 h1:pwQ0ejIdyj0HHdUomZzEGpzi8zTE8NMr55gwBGom8Y4= +github.com/cdklabs/awscdk-asset-awscli-go/awscliv1/v2 v2.2.229/go.mod h1:oquOkMHjv3uVsjt8ToBdJ3/i0HLD3RPEzuQlTzaieek= +github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.1.0 h1:kElXjprC8wkpJu58vp+WFH6z0AJw4zitg5iSKJPKe3c= +github.com/cdklabs/awscdk-asset-node-proxy-agent-go/nodeproxyagentv6/v2 v2.1.0/go.mod h1:JY4UnvNa1YDGQ4H5wohXTHl6YVY3uCDUWl4JYUrQfb8= +github.com/cdklabs/cloud-assembly-schema-go/awscdkcloudassemblyschema/v41 v41.0.0 h1:vUMERjQ8BFG4wW6DNW+sxF5fDCnAYOukvZEiRX4kRkw= +github.com/cdklabs/cloud-assembly-schema-go/awscdkcloudassemblyschema/v41 v41.0.0/go.mod h1:JNDQuA9sW21qkalkNLfhtii9NztdzL/lscAjDIKhbV0= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs= @@ -23,6 +37,8 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -48,6 +64,11 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U= github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA= github.com/mdlayher/vsock v1.2.1 h1:pC1mTJTvjo1r9n9fbm7S1j04rCgCzhCOS5DY0zqHlnQ= @@ -91,43 +112,55 @@ github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8 github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= +golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/tools/cdk/README.md b/tools/cdk/README.md new file mode 100644 index 0000000..4148008 --- /dev/null +++ b/tools/cdk/README.md @@ -0,0 +1,71 @@ +# Fixture collector + +This is an [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/home.html) app +that deploys ECS resources to AWS to enable real [task metadata +API](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-metadata-endpoint.html) +responses to be collected and versioned in this repository as test fixtures. +It's important to power our tests using real fixtures, as the documentation of +the task metadata API is not comprehensive or even perfectly accurate, and the +API is subject to change at any time. + +The expectation is that we collect sufficient fixtures to exercise all the +features of the exporter and all the hidden edge cases of the task metadata API +with respect to task configuration. So, for example, we know that ECS on EC2 and +on Fargate use completely different implementations of the API, so we should +deploy all tasks to both in order to collect fixtures from both. + +## How to update fixtures + +### Prerequisites + +You need to follow the [AWS CDK setup +guide](https://docs.aws.amazon.com/cdk/v2/guide/prerequisites.html). The full +details are there, but in short, you will need: +- NodeJS installed, with the `aws-cdk` NPM package globally installed. CDK is + written in Node. Even though our CDK app is written in Go, any non-NodeJS CDK + app is ultimately doing RPC to a NodeJS process using code generated from the + CDK NodeJS codebase. +- An AWS account, + [bootstrapped](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping-env.html) + to receive CDK deployments. +- The AWS CLI installed, with proper credentials for that account configured. + You also need the extra [Session Manager + plugin](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-exec.html) + for the CLI, to enable running commands inside task containers to actually + download the fixtures, using the CLI. + +Additionally, the update steps below use `jq` to query and pretty print JSON +output. + +### Update steps + +With all that done, the process works as follows: +1. Deploy our CDK app's stack, which will result in various ECS tasks being + launched. +2. Run commands in said tasks to produce the fixtures. +3. Destroy the stack, such that you are no longer paying money to AWS. + +In other words: + +```sh +# Prerequisite: you are authenticated to your AWS account. This can be done in +# multiple ways; one common way involves having an AWS_ACCESS_KEY_ID and +# AWS_SECRET_ACCESS_KEY set in the environment. + +# Deploy the stack. You will have to confirm the changes interactively. +cdk deploy + +# Update fixtures. We have to use `tail`/`head` to chop off non-JSON output +# printed by `aws ecs execute-command` to stdout. See: +# https://github.com/aws/session-manager-plugin/issues/85 +# +# We also use `jq` to sort parts of the output data to keep fixture diffs more +# readable - some things are not consistently ordered. +aws ecs execute-command --interactive --cluster prom-ecs-exporter-fixtures --task "$(aws ecs list-tasks --cluster prom-ecs-exporter-fixtures --service prom-ecs-exporter-fixtures-fargate | jq -r .taskArns[0])" --container ecs-exporter --command 'sh -c "wget -q -O- ${ECS_CONTAINER_METADATA_URI_V4}/task"' | tail -n4 | head -n1 | jq '.Containers |= sort_by(.Name)' > ../../ecscollector/testdata/fixtures/fargate_task_metadata.json +aws ecs execute-command --interactive --cluster prom-ecs-exporter-fixtures --task "$(aws ecs list-tasks --cluster prom-ecs-exporter-fixtures --service prom-ecs-exporter-fixtures-fargate | jq -r .taskArns[0])" --container ecs-exporter --command 'sh -c "wget -q -O- ${ECS_CONTAINER_METADATA_URI_V4}/task/stats"' | tail -n4 | head -n1 | jq 'to_entries | sort_by(.value.name) | from_entries' > ../../ecscollector/testdata/fixtures/fargate_task_stats.json +aws ecs execute-command --interactive --cluster prom-ecs-exporter-fixtures --task "$(aws ecs list-tasks --cluster prom-ecs-exporter-fixtures --service prom-ecs-exporter-fixtures-ec2 | jq -r .taskArns[0])" --container ecs-exporter --command 'sh -c "wget -q -O- ${ECS_CONTAINER_METADATA_URI_V4}/task"' | tail -n4 | head -n1 | jq '.Containers |= sort_by(.Name)' > ../../ecscollector/testdata/fixtures/ec2_task_metadata.json +aws ecs execute-command --interactive --cluster prom-ecs-exporter-fixtures --task "$(aws ecs list-tasks --cluster prom-ecs-exporter-fixtures --service prom-ecs-exporter-fixtures-ec2 | jq -r .taskArns[0])" --container ecs-exporter --command 'sh -c "wget -q -O- ${ECS_CONTAINER_METADATA_URI_V4}/task/stats"' | tail -n4 | head -n1 | jq 'to_entries | sort_by(.value.name) | from_entries' > ../../ecscollector/testdata/fixtures/ec2_task_stats.json + +# Destroy the stack. You will have to confirm the changes interactively. +cdk destroy +``` diff --git a/tools/cdk/cdk.json b/tools/cdk/cdk.json new file mode 100644 index 0000000..bb1b5d2 --- /dev/null +++ b/tools/cdk/cdk.json @@ -0,0 +1,72 @@ +{ + "app": "go run main.go", + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, + "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false, + "@aws-cdk/aws-ecs:disableEcsImdsBlocking": true, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true, + "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true, + "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true, + "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true, + "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true, + "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true, + "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true, + "@aws-cdk/core:enableAdditionalMetadataCollection": true, + "@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": true + } +} diff --git a/tools/cdk/main.go b/tools/cdk/main.go new file mode 100644 index 0000000..80d12c4 --- /dev/null +++ b/tools/cdk/main.go @@ -0,0 +1,206 @@ +// Copyright 2025 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "github.com/aws/aws-cdk-go/awscdk/v2" + "github.com/aws/aws-cdk-go/awscdk/v2/awsautoscaling" + "github.com/aws/aws-cdk-go/awscdk/v2/awsec2" + "github.com/aws/aws-cdk-go/awscdk/v2/awsecs" + "github.com/aws/aws-cdk-go/awscdk/v2/customresources" + "github.com/aws/constructs-go/constructs/v10" + "github.com/aws/jsii-runtime-go" +) + +type TetStackProps struct { + awscdk.StackProps +} + +func main() { + defer jsii.Close() + app := awscdk.NewApp(nil) + _ = NewFixtureCollectorStack(app, "FixtureCollectorStack") + app.Synth(nil) +} + +func NewFixtureCollectorStack(scope constructs.Construct, id string) awscdk.Stack { + stack := awscdk.NewStack(scope, &id, &awscdk.StackProps{}) + + // The human-readable name for many resources we create here. + resourceName := "prom-ecs-exporter-fixtures" + + vpc := awsec2.NewVpc(stack, jsii.String("Vpc"), &awsec2.VpcProps{MaxAzs: jsii.Number(1)}) + cluster := awsecs.NewCluster(stack, jsii.String("Cluster"), &awsecs.ClusterProps{ + ClusterName: &resourceName, + Vpc: vpc, + EnableFargateCapacityProviders: jsii.Bool(true), + }) + + // ASG capacity provider used for tasks on EC2 instances. + autoScalingGroup := awsautoscaling.NewAutoScalingGroup(stack, jsii.String("ASG"), &awsautoscaling.AutoScalingGroupProps{ + Vpc: vpc, + AutoScalingGroupName: &resourceName, + InstanceType: awsec2.NewInstanceType(jsii.String("t4g.nano")), + MachineImage: awsecs.EcsOptimizedImage_AmazonLinux2023(awsecs.AmiHardwareType_ARM, nil), + MinCapacity: jsii.Number(0), + MaxCapacity: jsii.Number(2), + BlockDevices: &[]*awsautoscaling.BlockDevice{ + {DeviceName: jsii.String("/dev/xvda"), Volume: awsautoscaling.BlockDeviceVolume_Ebs(jsii.Number(40), nil)}, + }, + NewInstancesProtectedFromScaleIn: jsii.Bool(true), + }) + // https://github.com/aws/aws-cdk/issues/18179#issuecomment-1150981559 + customresources.NewAwsCustomResource(stack, jsii.String("AsgForceDelete"), &customresources.AwsCustomResourceProps{ + OnDelete: &customresources.AwsSdkCall{ + Service: jsii.String("AutoScaling"), + Action: jsii.String("deleteAutoScalingGroup"), + Parameters: map[string]any{ + "AutoScalingGroupName": autoScalingGroup.AutoScalingGroupName(), + "ForceDelete": jsii.Bool(true), + }, + }, + Policy: customresources.AwsCustomResourcePolicy_FromSdkCalls(&customresources.SdkCallsPolicyOptions{ + Resources: customresources.AwsCustomResourcePolicy_ANY_RESOURCE(), + }), + }).Node().AddDependency(autoScalingGroup) + + capacityProvider := awsecs.NewAsgCapacityProvider(stack, jsii.String("Capacity"), &awsecs.AsgCapacityProviderProps{ + CapacityProviderName: &resourceName, + InstanceWarmupPeriod: jsii.Number(0), + EnableManagedTerminationProtection: jsii.Bool(true), + AutoScalingGroup: autoScalingGroup, + }) + cluster.AddAsgCapacityProvider(capacityProvider, nil) + + // We do not strictly need such an image to capture the fixtures we need, + // but given that there should always be an ecs-exporter sidecar in every + // real Task, it would be strange not to include in the fixture data here. + ecsExporterImage := awsecs.ContainerImage_FromRegistry(jsii.String("quay.io/prometheuscommunity/ecs-exporter:v0.4.0"), nil) + + { + // Create an EC2 task. + taskDefinition := awsecs.NewTaskDefinition(stack, jsii.String("Ec2TaskDefinition"), &awsecs.TaskDefinitionProps{ + Family: jsii.String("ecs-exporter-fixtures-ec2"), + NetworkMode: awsecs.NetworkMode_AWS_VPC, + Compatibility: awsecs.Compatibility_EC2, + MemoryMiB: jsii.String("256"), + }) + taskDefinition.AddContainer(jsii.String("EcsExporter"), &awsecs.ContainerDefinitionOptions{ + ContainerName: jsii.String("ecs-exporter"), + Image: ecsExporterImage, + MemoryReservationMiB: jsii.Number(128), + MemoryLimitMiB: jsii.Number(128), + Cpu: jsii.Number(128), + }) + taskDefinition.AddContainer(jsii.String("AlpineShell"), &awsecs.ContainerDefinitionOptions{ + ContainerName: jsii.String("main"), + Image: awsecs.ContainerImage_FromRegistry(jsii.String("alpine"), nil), + // Hang on forever. + Command: &[]*string{jsii.String("sh"), jsii.String("-c"), jsii.String("sleep infinity")}, + }) + taskDefinition.AddContainer(jsii.String("Nonessential"), &awsecs.ContainerDefinitionOptions{ + ContainerName: jsii.String("nonessential"), + Image: awsecs.ContainerImage_FromRegistry(jsii.String("alpine"), nil), + Command: &[]*string{jsii.String("sh"), jsii.String("-c"), jsii.String("echo goodbye")}, + MemoryReservationMiB: jsii.Number(128), + MemoryLimitMiB: jsii.Number(128), + Cpu: jsii.Number(128), + Essential: jsii.Bool(false), + }) + + service := awsecs.NewEc2Service(stack, jsii.String("Ec2Service"), &awsecs.Ec2ServiceProps{ + ServiceName: jsii.String(resourceName + "-ec2"), + Cluster: cluster, + TaskDefinition: taskDefinition, + DesiredCount: jsii.Number(1), + MinHealthyPercent: jsii.Number(0), + CapacityProviderStrategies: &[]*awsecs.CapacityProviderStrategy{ + {CapacityProvider: capacityProvider.CapacityProviderName(), Weight: jsii.Number(1)}, + }, + EnableExecuteCommand: jsii.Bool(true), + }) + // Deletion does not work if we don't do this - the VPC will tear down + // route tables etc before we can delete the cluster/capacity provider, + // leaving instances and their tasks in limbo. + vpcConstructs := *vpc.Node().FindAll(constructs.ConstructOrder_PREORDER) + vpcDependables := make([]constructs.IDependable, len(vpcConstructs)) + for i, c := range vpcConstructs { + vpcDependables[i] = c + } + service.Node().AddDependency(vpcDependables...) + } + + { + // Create a Fargate task. + taskDefinition := awsecs.NewFargateTaskDefinition(stack, jsii.String("FargateTaskDefinition"), &awsecs.FargateTaskDefinitionProps{ + Family: jsii.String("ecs-exporter-fixtures-fargate"), + RuntimePlatform: &awsecs.RuntimePlatform{ + CpuArchitecture: awsecs.CpuArchitecture_ARM64(), + OperatingSystemFamily: awsecs.OperatingSystemFamily_LINUX(), + }, + }) + taskDefinition.AddContainer(jsii.String("EcsExporter"), &awsecs.ContainerDefinitionOptions{ + ContainerName: jsii.String("ecs-exporter"), + Image: ecsExporterImage, + MemoryReservationMiB: jsii.Number(128), + MemoryLimitMiB: jsii.Number(128), + Cpu: jsii.Number(128), + }) + taskDefinition.AddContainer(jsii.String("AlpineShell"), &awsecs.ContainerDefinitionOptions{ + ContainerName: jsii.String("main"), + Image: awsecs.ContainerImage_FromRegistry(jsii.String("alpine"), nil), + // Hang on forever. + Command: &[]*string{jsii.String("sh"), jsii.String("-c"), jsii.String("sleep infinity")}, + }) + taskDefinition.AddContainer(jsii.String("Nonessential"), &awsecs.ContainerDefinitionOptions{ + ContainerName: jsii.String("nonessential"), + Image: awsecs.ContainerImage_FromRegistry(jsii.String("alpine"), nil), + Command: &[]*string{jsii.String("sh"), jsii.String("-c"), jsii.String("echo goodbye")}, + MemoryReservationMiB: jsii.Number(128), + MemoryLimitMiB: jsii.Number(128), + Cpu: jsii.Number(128), + Essential: jsii.Bool(false), + }) + + awsecs.NewFargateService(stack, jsii.String("FargateService"), &awsecs.FargateServiceProps{ + ServiceName: jsii.String(resourceName + "-fargate"), + Cluster: cluster, + TaskDefinition: taskDefinition, + DesiredCount: jsii.Number(1), + MinHealthyPercent: jsii.Number(0), + EnableExecuteCommand: jsii.Bool(true), + }) + } + + awscdk.Aspects_Of(stack).Add(&CapacityProviderDependencyAspect{}, nil) + + return stack +} + +type CapacityProviderDependencyAspect struct{} + +// Add a dependency from capacity provider association to the cluster +// and from each service to the capacity provider association. +// +// https://github.com/aws/aws-cdk/issues/19275#issuecomment-1152860147 +func (CapacityProviderDependencyAspect) Visit(node constructs.IConstruct) { + if service, ok := node.(awsecs.Ec2Service); ok { + for _, child := range *service.Cluster().Node().FindAll(constructs.ConstructOrder_PREORDER) { + if assoc, ok := child.(awsecs.CfnClusterCapacityProviderAssociations); ok { + assoc.Node().AddDependency(service.Cluster()) + service.Node().AddDependency(assoc) + } + } + } +}