4
4
"fmt"
5
5
"time"
6
6
7
+ "github.com/google/uuid"
7
8
"github.com/prometheus/client_golang/prometheus"
8
9
"github.com/prometheus/common/log"
9
10
"github.com/showwin/speedtest-go/speedtest"
@@ -17,29 +18,29 @@ var (
17
18
up = prometheus .NewDesc (
18
19
prometheus .BuildFQName (namespace , "" , "up" ),
19
20
"Was the last speedtest successful." ,
20
- nil , nil ,
21
+ [] string { "test_uuid" } , nil ,
21
22
)
22
23
scrapeDurationSeconds = prometheus .NewDesc (
23
24
prometheus .BuildFQName (namespace , "" , "scrape_duration_seconds" ),
24
25
"Time to preform last speed test" ,
25
- nil , nil ,
26
+ [] string { "test_uuid" } , nil ,
26
27
)
27
28
latency = prometheus .NewDesc (
28
29
prometheus .BuildFQName (namespace , "" , "latency_seconds" ),
29
30
"Measured latency on last speed test" ,
30
- []string {"user_lat" , "user_lon" , "user_ip" , "user_isp" , "server_lat" , "server_lon" , "server_id" , "server_name" , "server_country" , "distance" },
31
+ []string {"test_uuid" , " user_lat" , "user_lon" , "user_ip" , "user_isp" , "server_lat" , "server_lon" , "server_id" , "server_name" , "server_country" , "distance" },
31
32
nil ,
32
33
)
33
34
upload = prometheus .NewDesc (
34
35
prometheus .BuildFQName (namespace , "" , "upload_speed_Bps" ),
35
36
"Last upload speedtest result" ,
36
- []string {"user_lat" , "user_lon" , "user_ip" , "user_isp" , "server_lat" , "server_lon" , "server_id" , "server_name" , "server_country" , "distance" },
37
+ []string {"test_uuid" , " user_lat" , "user_lon" , "user_ip" , "user_isp" , "server_lat" , "server_lon" , "server_id" , "server_name" , "server_country" , "distance" },
37
38
nil ,
38
39
)
39
40
download = prometheus .NewDesc (
40
41
prometheus .BuildFQName (namespace , "" , "download_speed_Bps" ),
41
42
"Last download speedtest result" ,
42
- []string {"user_lat" , "user_lon" , "user_ip" , "user_isp" , "server_lat" , "server_lon" , "server_id" , "server_name" , "server_country" , "distance" },
43
+ []string {"test_uuid" , " user_lat" , "user_lon" , "user_ip" , "user_isp" , "server_lat" , "server_lon" , "server_id" , "server_name" , "server_country" , "distance" },
43
44
nil ,
44
45
)
45
46
)
@@ -66,24 +67,28 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
66
67
// as Prometheus metrics. It implements prometheus.Collector.
67
68
func (e * Exporter ) Collect (ch chan <- prometheus.Metric ) {
68
69
start := time .Now ()
69
- ok := e .speedtest (ch )
70
+ testUUID := uuid .New ().String ()
71
+ ok := e .speedtest (testUUID , ch )
70
72
d := time .Since (start ).Seconds ()
71
73
72
74
if ok {
73
75
ch <- prometheus .MustNewConstMetric (
74
76
up , prometheus .GaugeValue , 1.0 ,
77
+ testUUID ,
75
78
)
76
79
ch <- prometheus .MustNewConstMetric (
77
80
scrapeDurationSeconds , prometheus .GaugeValue , d ,
81
+ testUUID ,
78
82
)
79
83
} else {
80
84
ch <- prometheus .MustNewConstMetric (
81
85
up , prometheus .GaugeValue , 0.0 ,
86
+ testUUID ,
82
87
)
83
88
}
84
89
}
85
90
86
- func (e * Exporter ) speedtest (ch chan <- prometheus.Metric ) bool {
91
+ func (e * Exporter ) speedtest (testUUID string , ch chan <- prometheus.Metric ) bool {
87
92
user , err := speedtest .FetchUserInfo ()
88
93
if err != nil {
89
94
log .Errorf ("could not fetch user information: %s" , err .Error ())
@@ -100,59 +105,87 @@ func (e *Exporter) speedtest(ch chan<- prometheus.Metric) bool {
100
105
servers := serverList .Servers
101
106
server := servers [0 ]
102
107
103
- if err := server .PingTest (); err == nil {
104
- ch <- prometheus .MustNewConstMetric (
105
- latency , prometheus .GaugeValue , server .Latency .Seconds (),
106
- user .Lat ,
107
- user .Lon ,
108
- user .IP ,
109
- user .Isp ,
110
- server .Lat ,
111
- server .Lon ,
112
- server .ID ,
113
- server .Name ,
114
- server .Country ,
115
- fmt .Sprintf ("%f" , server .Distance ),
116
- )
117
- } else {
108
+ ok := pingTest (testUUID , user , server , ch )
109
+ ok = downloadTest (testUUID , user , server , ch ) && ok
110
+ ok = uploadTest (testUUID , user , server , ch ) && ok
111
+
112
+ if ok {
113
+ return true
114
+ }
115
+ return false
116
+ }
117
+
118
+ func pingTest (testUUID string , user * speedtest.User , server * speedtest.Server , ch chan <- prometheus.Metric ) bool {
119
+ err := server .PingTest ()
120
+ if err != nil {
118
121
log .Errorf ("failed to carry out ping test: %s" , err .Error ())
122
+ return false
119
123
}
120
124
121
- if err := server .DownloadTest (false ); err == nil {
122
- ch <- prometheus .MustNewConstMetric (
123
- download , prometheus .GaugeValue , server .DLSpeed * 1024 * 1024 ,
124
- user .Lat ,
125
- user .Lon ,
126
- user .IP ,
127
- user .Isp ,
128
- server .Lat ,
129
- server .Lon ,
130
- server .ID ,
131
- server .Name ,
132
- server .Country ,
133
- fmt .Sprintf ("%f" , server .Distance ),
134
- )
135
- } else {
125
+ ch <- prometheus .MustNewConstMetric (
126
+ latency , prometheus .GaugeValue , server .Latency .Seconds (),
127
+ testUUID ,
128
+ user .Lat ,
129
+ user .Lon ,
130
+ user .IP ,
131
+ user .Isp ,
132
+ server .Lat ,
133
+ server .Lon ,
134
+ server .ID ,
135
+ server .Name ,
136
+ server .Country ,
137
+ fmt .Sprintf ("%f" , server .Distance ),
138
+ )
139
+
140
+ return true
141
+ }
142
+
143
+ func downloadTest (testUUID string , user * speedtest.User , server * speedtest.Server , ch chan <- prometheus.Metric ) bool {
144
+ err := server .DownloadTest (false )
145
+ if err != nil {
136
146
log .Errorf ("failed to carry out download test: %s" , err .Error ())
147
+ return false
137
148
}
138
149
139
- if err := server .UploadTest (false ); err == nil {
140
- ch <- prometheus .MustNewConstMetric (
141
- upload , prometheus .GaugeValue , server .ULSpeed * 1024 * 1024 ,
142
- user .Lat ,
143
- user .Lon ,
144
- user .IP ,
145
- user .Isp ,
146
- server .Lat ,
147
- server .Lon ,
148
- server .ID ,
149
- server .Name ,
150
- server .Country ,
151
- fmt .Sprintf ("%f" , server .Distance ),
152
- )
153
- } else {
150
+ ch <- prometheus .MustNewConstMetric (
151
+ download , prometheus .GaugeValue , server .DLSpeed * 1024 * 1024 ,
152
+ testUUID ,
153
+ user .Lat ,
154
+ user .Lon ,
155
+ user .IP ,
156
+ user .Isp ,
157
+ server .Lat ,
158
+ server .Lon ,
159
+ server .ID ,
160
+ server .Name ,
161
+ server .Country ,
162
+ fmt .Sprintf ("%f" , server .Distance ),
163
+ )
164
+
165
+ return true
166
+ }
167
+
168
+ func uploadTest (testUUID string , user * speedtest.User , server * speedtest.Server , ch chan <- prometheus.Metric ) bool {
169
+ err := server .UploadTest (false )
170
+ if err != nil {
154
171
log .Errorf ("failed to carry out upload test: %s" , err .Error ())
172
+ return false
155
173
}
156
174
175
+ ch <- prometheus .MustNewConstMetric (
176
+ upload , prometheus .GaugeValue , server .ULSpeed * 1024 * 1024 ,
177
+ testUUID ,
178
+ user .Lat ,
179
+ user .Lon ,
180
+ user .IP ,
181
+ user .Isp ,
182
+ server .Lat ,
183
+ server .Lon ,
184
+ server .ID ,
185
+ server .Name ,
186
+ server .Country ,
187
+ fmt .Sprintf ("%f" , server .Distance ),
188
+ )
189
+
157
190
return true
158
191
}
0 commit comments