diff --git a/collector/aws.go b/collector/aws.go index 4d7ad25..581b178 100644 --- a/collector/aws.go +++ b/collector/aws.go @@ -170,11 +170,12 @@ func (e *ECSClient) GetClusterServices(cluster *types.ECSCluster) ([]*types.ECSS for _, s := range resp.Services { es := &types.ECSService{ - ID: aws.StringValue(s.ServiceArn), - Name: aws.StringValue(s.ServiceName), - DesiredT: aws.Int64Value(s.DesiredCount), - RunningT: aws.Int64Value(s.RunningCount), - PendingT: aws.Int64Value(s.PendingCount), + ID: aws.StringValue(s.ServiceArn), + Name: aws.StringValue(s.ServiceName), + DesiredT: aws.Int64Value(s.DesiredCount), + RunningT: aws.Int64Value(s.RunningCount), + PendingT: aws.Int64Value(s.PendingCount), + Deployments: len(s.Deployments), } ss = append(ss, es) } diff --git a/collector/aws_test.go b/collector/aws_test.go index 6d19a8e..1b1ffd3 100644 --- a/collector/aws_test.go +++ b/collector/aws_test.go @@ -99,21 +99,21 @@ func TestGetClusterServices(t *testing.T) { }{ { []*types.ECSService{ - &types.ECSService{ID: "s1", Name: "service1", PendingT: 1, RunningT: 9, DesiredT: 10}, - &types.ECSService{ID: "s2", Name: "service2", PendingT: 5, RunningT: 5, DesiredT: 10}, - &types.ECSService{ID: "s3", Name: "service3", PendingT: 7, RunningT: 3, DesiredT: 10}, + &types.ECSService{ID: "s1", Name: "service1", PendingT: 1, RunningT: 9, DesiredT: 10, Deployments: 2}, + &types.ECSService{ID: "s2", Name: "service2", PendingT: 5, RunningT: 5, DesiredT: 10, Deployments: 2}, + &types.ECSService{ID: "s3", Name: "service3", PendingT: 7, RunningT: 3, DesiredT: 10, Deployments: 2}, }, false, false, false, }, { []*types.ECSService{ - &types.ECSService{ID: "s1", Name: "service1", PendingT: 1, RunningT: 9, DesiredT: 10}, + &types.ECSService{ID: "s1", Name: "service1", PendingT: 1, RunningT: 9, DesiredT: 10, Deployments: 2}, }, true, false, true, }, { []*types.ECSService{ - &types.ECSService{ID: "s1", Name: "service1", PendingT: 1, RunningT: 9, DesiredT: 10}, + &types.ECSService{ID: "s1", Name: "service1", PendingT: 1, RunningT: 9, DesiredT: 10, Deployments: 2}, }, true, true, true, }, diff --git a/collector/collector.go b/collector/collector.go index 557adb6..e6b9b99 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -59,6 +59,12 @@ var ( []string{"region", "cluster", "service"}, nil, ) + serviceDeployments = prometheus.NewDesc( + prometheus.BuildFQName(namespace, "", "service_deployments"), + "The number of deployments regarding a service", + []string{"region", "cluster", "service"}, nil, + ) + // Container instances metrics cInstanceCount = prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "container_instances"), @@ -145,6 +151,7 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { ch <- serviceDesired ch <- servicePending ch <- serviceRunning + ch <- serviceDeployments if e.noCIMetrics { return @@ -263,6 +270,9 @@ func (e *Exporter) collectClusterServicesMetrics(ctx context.Context, ch chan<- // Running task count sendSafeMetric(ctx, ch, prometheus.MustNewConstMetric(serviceRunning, prometheus.GaugeValue, float64(s.RunningT), e.region, cluster.Name, s.Name)) + + // Deployment count + sendSafeMetric(ctx, ch, prometheus.MustNewConstMetric(serviceDeployments, prometheus.GaugeValue, float64(s.Deployments), e.region, cluster.Name, s.Name)) } } diff --git a/collector/collector_test.go b/collector/collector_test.go index 062c9e7..11e9f1c 100644 --- a/collector/collector_test.go +++ b/collector/collector_test.go @@ -83,12 +83,12 @@ func TestCollectClusterServiceMetrics(t *testing.T) { testC := &types.ECSCluster{ID: "c1", Name: "cluster1"} testSs := []*types.ECSService{ - &types.ECSService{ID: "s1", Name: "service1", DesiredT: 10, PendingT: 5, RunningT: 5}, - &types.ECSService{ID: "s2", Name: "service2", DesiredT: 15, PendingT: 5, RunningT: 10}, - &types.ECSService{ID: "s3", Name: "service3", DesiredT: 30, PendingT: 27, RunningT: 0}, - &types.ECSService{ID: "s4", Name: "service4", DesiredT: 51, PendingT: 50, RunningT: 1}, - &types.ECSService{ID: "s5", Name: "service5", DesiredT: 109, PendingT: 99, RunningT: 2}, - &types.ECSService{ID: "s6", Name: "service6", DesiredT: 6431, PendingT: 5000, RunningT: 107}, + &types.ECSService{ID: "s1", Name: "service1", DesiredT: 10, PendingT: 5, RunningT: 5, Deployments: 2}, + &types.ECSService{ID: "s2", Name: "service2", DesiredT: 15, PendingT: 5, RunningT: 10, Deployments: 2}, + &types.ECSService{ID: "s3", Name: "service3", DesiredT: 30, PendingT: 27, RunningT: 0, Deployments: 2}, + &types.ECSService{ID: "s4", Name: "service4", DesiredT: 51, PendingT: 50, RunningT: 1, Deployments: 2}, + &types.ECSService{ID: "s5", Name: "service5", DesiredT: 109, PendingT: 99, RunningT: 2, Deployments: 2}, + &types.ECSService{ID: "s6", Name: "service6", DesiredT: 6431, PendingT: 5000, RunningT: 107, Deployments: 2}, } // Collect mocked metrics go func() { @@ -144,6 +144,18 @@ func TestCollectClusterServiceMetrics(t *testing.T) { if expected != m.Desc().String() { t.Errorf("expected '%s', \ngot '%s'", expected, m.Desc().String()) } + + // Check 1st received metric per service (deployments) + m = (<-ch).(prometheus.Metric) + m2 = readGauge(m) + want = float64(wantS.Deployments) + if m2.value != want { + t.Errorf("expected %f service_deployments, got %f", want, m2.value) + } + expected = `Desc{fqName: "ecs_service_deployments", help: "The number of deployments regarding a service", constLabels: {}, variableLabels: [region cluster service]}` + if expected != m.Desc().String() { + t.Errorf("expected '%s', \ngot '%s'", expected, m.Desc().String()) + } } } diff --git a/mock/aws/ecs_mock_utils.go b/mock/aws/ecs_mock_utils.go index c3891e7..66daf4d 100644 --- a/mock/aws/ecs_mock_utils.go +++ b/mock/aws/ecs_mock_utils.go @@ -92,6 +92,7 @@ func MockECSDescribeServices(t *testing.T, mockMatcher *sdk.MockECSAPI, wantErro PendingCount: aws.Int64(s.PendingT), RunningCount: aws.Int64(s.RunningT), DesiredCount: aws.Int64(s.DesiredT), + Deployments: make([]*ecs.Deployment, s.Deployments), } ss = append(ss, ds) } diff --git a/types/types.go b/types/types.go index cde61a0..b1e5e5e 100644 --- a/types/types.go +++ b/types/types.go @@ -10,6 +10,7 @@ type ECSService struct { ID string // Service ARN Name string // Name of the service DesiredT, PendingT, RunningT int64 // Service task information + Deployments int // Number of deployments } // ECSCluster reprensens a cluster on ECS