Skip to content
This repository was archived by the owner on Mar 8, 2023. It is now read-only.

Commit 880ea50

Browse files
author
Mathieu
committed
Added the regex functionality
1 parent 4e92259 commit 880ea50

File tree

3 files changed

+108
-29
lines changed

3 files changed

+108
-29
lines changed

aws.go

+95-28
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package main
22

33
import (
4+
"fmt"
45
"github.com/aws/aws-sdk-go/aws"
56
"github.com/aws/aws-sdk-go/aws/session"
67
"github.com/aws/aws-sdk-go/service/cloudwatch"
78
"github.com/prometheus/client_golang/prometheus"
89
"time"
9-
"fmt"
10+
"regexp"
1011
)
1112

1213
func getLatestDatapoint(datapoints []*cloudwatch.Datapoint) *cloudwatch.Datapoint {
@@ -29,7 +30,6 @@ func scrape(collector *cwCollector, ch chan<- prometheus.Metric) {
2930
}))
3031

3132
svc := cloudwatch.New(session)
32-
3333
for m := range collector.Template.Metrics {
3434
metric := &collector.Template.Metrics[m]
3535

@@ -48,6 +48,9 @@ func scrape(collector *cwCollector, ch chan<- prometheus.Metric) {
4848
Unit: nil,
4949
}
5050

51+
dimensions:=[]*cloudwatch.Dimension{}
52+
53+
5154
for _, stat := range metric.ConfMetric.Statistics {
5255
params.Statistics = append(params.Statistics, aws.String(stat))
5356
}
@@ -64,7 +67,7 @@ func scrape(collector *cwCollector, ch chan<- prometheus.Metric) {
6467
dimValue = collector.Target
6568
}
6669

67-
params.Dimensions = append(params.Dimensions, &cloudwatch.Dimension{
70+
dimensions = append(dimensions, &cloudwatch.Dimension{
6871
Name: aws.String(dim),
6972
Value: aws.String(dimValue),
7073
})
@@ -73,43 +76,107 @@ func scrape(collector *cwCollector, ch chan<- prometheus.Metric) {
7376
}
7477
}
7578

76-
labels = append(labels, collector.Template.Task.Name)
79+
if (len(dimensions)>0){
80+
labels = append(labels, collector.Template.Task.Name)
81+
params.Dimensions=dimensions
82+
scrapeSingleDataPoint(collector,ch,params,metric,labels,svc)
83+
continue
84+
}
7785

78-
// Call CloudWatch to gather the datapoints
79-
resp, err := svc.GetMetricStatistics(params)
80-
totalRequests.Inc()
86+
// Get all the metric to select the ones who'll match the regex
87+
result, err := svc.ListMetrics(&cloudwatch.ListMetricsInput{
88+
MetricName: aws.String(metric.ConfMetric.Name),
89+
Namespace: aws.String(metric.ConfMetric.Namespace),
90+
})
8191

8292
if err != nil {
83-
collector.ErroneousRequests.Inc()
8493
fmt.Println(err)
8594
continue
8695
}
96+
97+
//This map will hold dimensions name which has been already collected
98+
valueCollected := map[string]bool{}
8799

88-
// There's nothing in there, don't publish the metric
89-
if len(resp.Datapoints) == 0 {
90-
continue
91-
}
100+
for dimensions := range metric.ConfMetric.DimensionsSelectRegex {
101+
dimRegex := metric.ConfMetric.DimensionsSelectRegex[dimensions]
92102

93-
// Pick the latest datapoint
94-
dp := getLatestDatapoint(resp.Datapoints)
95-
if dp.Sum != nil {
96-
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.Sum), labels...)
97-
}
103+
// Replace $_target token by the actual URL target
104+
if dimRegex == "$_target" {
105+
dimRegex = collector.Target
106+
}
98107

99-
if dp.Average != nil {
100-
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.Average), labels...)
108+
//Loop through all the dimensions for the metric given
109+
for _,met := range result.Metrics {
110+
for _,dim := range met.Dimensions {
111+
112+
//Select the one which match the regex
113+
match,_:=regexp.MatchString(dimRegex,*dim.Value)
114+
if _, ok := valueCollected[*dim.Value]; match && !ok {
115+
//Create the request and send it to the prometheus lib
116+
labels := make([]string, 0, len(metric.LabelNames))
117+
118+
params.Dimensions = []*cloudwatch.Dimension{}
119+
params.Dimensions = append(params.Dimensions, &cloudwatch.Dimension{
120+
Name: aws.String(*dim.Name),
121+
Value: aws.String(*dim.Value),
122+
})
123+
124+
labels = append(labels, *dim.Value)
125+
126+
labels = append(labels, collector.Template.Task.Name)
127+
scrapeSingleDataPoint(collector,ch,params,metric,labels,svc)
128+
129+
valueCollected[*dim.Value]=true
130+
}
131+
}
132+
133+
134+
}
101135
}
102136

103-
if dp.Maximum != nil {
104-
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.Maximum), labels...)
105-
}
106137

107-
if dp.Minimum != nil {
108-
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.Minimum), labels...)
109-
}
138+
139+
}
140+
}
110141

111-
if dp.SampleCount != nil {
112-
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.SampleCount), labels...)
113-
}
142+
//Send a single dataPoint to the Prometheus lib
143+
func scrapeSingleDataPoint(collector *cwCollector, ch chan<- prometheus.Metric,params *cloudwatch.GetMetricStatisticsInput,metric *cwMetric,labels []string,svc *cloudwatch.CloudWatch) error {
144+
145+
resp, err := svc.GetMetricStatistics(params)
146+
totalRequests.Inc()
147+
148+
if err != nil {
149+
collector.ErroneousRequests.Inc()
150+
fmt.Println(err)
151+
return err
152+
}
153+
154+
// There's nothing in there, don't publish the metric
155+
if len(resp.Datapoints) == 0 {
156+
return nil
157+
}
158+
// Pick the latest datapoint
159+
dp := getLatestDatapoint(resp.Datapoints)
160+
161+
162+
if dp.Sum != nil {
163+
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.Sum), labels...)
164+
}
165+
166+
if dp.Average != nil {
167+
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.Average), labels...)
168+
}
169+
170+
if dp.Maximum != nil {
171+
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.Maximum), labels...)
172+
}
173+
174+
if dp.Minimum != nil {
175+
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.Minimum), labels...)
176+
}
177+
178+
if dp.SampleCount != nil {
179+
ch <- prometheus.MustNewConstMetric(metric.Desc, metric.ValType, float64(*dp.SampleCount), labels...)
114180
}
181+
return nil
115182
}

config.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,15 @@ tasks:
5050
VpnId: [$_target]
5151
aws_metric_name: TunnelDataOut
5252
aws_statistics: [Average]
53-
range_seconds: 3600
53+
range_seconds: 3600
54+
- name: lambda_duration
55+
default_region: eu-west-1
56+
metrics:
57+
- aws_namespace: "AWS/Lambda"
58+
aws_dimensions: [FunctionName]
59+
aws_dimensions_select_regex:
60+
FunctionName: .*
61+
aws_metric_name: Duration
62+
aws_statistics: [Maximum]
63+
range_seconds: 1728000
64+
period_seconds: 3000

config/config.go

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ type Metric struct {
1515
Statistics []string `yaml:"aws_statistics"`
1616
Dimensions []string `yaml:"aws_dimensions,omitempty"`
1717
DimensionsSelect map[string][]string `yaml:"aws_dimensions_select,omitempty"`
18+
DimensionsSelectRegex map[string]string `yaml:"aws_dimensions_select_regex,omitempty"`
1819
DimensionsSelectParam map[string][]string `yaml:"aws_dimensions_select_param,omitempty"`
1920

2021
RangeSeconds int `yaml:"range_seconds,omitempty"`

0 commit comments

Comments
 (0)