1
1
package main
2
2
3
3
import (
4
+ "fmt"
4
5
"github.com/aws/aws-sdk-go/aws"
5
6
"github.com/aws/aws-sdk-go/aws/session"
6
7
"github.com/aws/aws-sdk-go/service/cloudwatch"
7
8
"github.com/prometheus/client_golang/prometheus"
8
9
"time"
9
- "fmt "
10
+ "regexp "
10
11
)
11
12
12
13
func getLatestDatapoint (datapoints []* cloudwatch.Datapoint ) * cloudwatch.Datapoint {
@@ -29,7 +30,6 @@ func scrape(collector *cwCollector, ch chan<- prometheus.Metric) {
29
30
}))
30
31
31
32
svc := cloudwatch .New (session )
32
-
33
33
for m := range collector .Template .Metrics {
34
34
metric := & collector .Template .Metrics [m ]
35
35
@@ -48,6 +48,9 @@ func scrape(collector *cwCollector, ch chan<- prometheus.Metric) {
48
48
Unit : nil ,
49
49
}
50
50
51
+ dimensions := []* cloudwatch.Dimension {}
52
+
53
+
51
54
for _ , stat := range metric .ConfMetric .Statistics {
52
55
params .Statistics = append (params .Statistics , aws .String (stat ))
53
56
}
@@ -64,7 +67,7 @@ func scrape(collector *cwCollector, ch chan<- prometheus.Metric) {
64
67
dimValue = collector .Target
65
68
}
66
69
67
- params . Dimensions = append (params . Dimensions , & cloudwatch.Dimension {
70
+ dimensions = append (dimensions , & cloudwatch.Dimension {
68
71
Name : aws .String (dim ),
69
72
Value : aws .String (dimValue ),
70
73
})
@@ -73,43 +76,107 @@ func scrape(collector *cwCollector, ch chan<- prometheus.Metric) {
73
76
}
74
77
}
75
78
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
+ }
77
85
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
+ })
81
91
82
92
if err != nil {
83
- collector .ErroneousRequests .Inc ()
84
93
fmt .Println (err )
85
94
continue
86
95
}
96
+
97
+ //This map will hold dimensions name which has been already collected
98
+ valueCollected := map [string ]bool {}
87
99
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 ]
92
102
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
+ }
98
107
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
+ }
101
135
}
102
136
103
- if dp .Maximum != nil {
104
- ch <- prometheus .MustNewConstMetric (metric .Desc , metric .ValType , float64 (* dp .Maximum ), labels ... )
105
- }
106
137
107
- if dp . Minimum != nil {
108
- ch <- prometheus . MustNewConstMetric ( metric . Desc , metric . ValType , float64 ( * dp . Minimum ), labels ... )
109
- }
138
+
139
+ }
140
+ }
110
141
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 ... )
114
180
}
181
+ return nil
115
182
}
0 commit comments