@@ -143,117 +143,13 @@ func main() {
143
143
esURL .User = url .UserPassword (esUsername , esPassword )
144
144
}
145
145
146
- // returns nil if not provided and falls back to simple TCP.
147
- tlsConfig := createTLSConfig (* esCA , * esClientCert , * esClientPrivateKey , * esInsecureSkipVerify )
148
-
149
- var httpTransport http.RoundTripper
150
-
151
- httpTransport = & http.Transport {
152
- TLSClientConfig : tlsConfig ,
153
- Proxy : http .ProxyFromEnvironment ,
154
- }
155
-
156
- esAPIKey := os .Getenv ("ES_API_KEY" )
157
-
158
- if esAPIKey != "" {
159
- httpTransport = & transportWithAPIKey {
160
- underlyingTransport : httpTransport ,
161
- apiKey : esAPIKey ,
162
- }
163
- }
164
-
165
- httpClient := & http.Client {
166
- Timeout : * esTimeout ,
167
- Transport : httpTransport ,
168
- }
169
-
170
- if * awsRegion != "" {
171
- httpClient .Transport , err = roundtripper .NewAWSSigningTransport (httpTransport , * awsRegion , * awsRoleArn , logger )
172
- if err != nil {
173
- level .Error (logger ).Log ("msg" , "failed to create AWS transport" , "err" , err )
174
- os .Exit (1 )
175
- }
176
- }
177
-
178
- // version metric
179
- prometheus .MustRegister (version .NewCollector (name ))
180
-
181
- // create the exporter
182
- exporter , err := collector .NewElasticsearchCollector (
183
- logger ,
184
- []string {},
185
- collector .WithElasticsearchURL (esURL ),
186
- collector .WithHTTPClient (httpClient ),
187
- )
188
- if err != nil {
189
- level .Error (logger ).Log ("msg" , "failed to create Elasticsearch collector" , "err" , err )
190
- os .Exit (1 )
191
- }
192
- prometheus .MustRegister (exporter )
193
-
194
- // TODO(@sysadmind): Remove this when we have a better way to get the cluster name to down stream collectors.
195
- // cluster info retriever
196
- clusterInfoRetriever := clusterinfo .New (logger , httpClient , esURL , * esClusterInfoInterval )
197
-
198
- prometheus .MustRegister (collector .NewClusterHealth (logger , httpClient , esURL ))
199
- prometheus .MustRegister (collector .NewNodes (logger , httpClient , esURL , * esAllNodes , * esNode ))
200
-
201
- if * esExportIndices || * esExportShards {
202
- sC := collector .NewShards (logger , httpClient , esURL )
203
- prometheus .MustRegister (sC )
204
- iC := collector .NewIndices (logger , httpClient , esURL , * esExportShards , * esExportIndexAliases )
205
- prometheus .MustRegister (iC )
206
- if registerErr := clusterInfoRetriever .RegisterConsumer (iC ); registerErr != nil {
207
- level .Error (logger ).Log ("msg" , "failed to register indices collector in cluster info" )
208
- os .Exit (1 )
209
- }
210
- if registerErr := clusterInfoRetriever .RegisterConsumer (sC ); registerErr != nil {
211
- level .Error (logger ).Log ("msg" , "failed to register shards collector in cluster info" )
212
- os .Exit (1 )
213
- }
214
- }
215
-
216
- if * esExportSLM {
217
- prometheus .MustRegister (collector .NewSLM (logger , httpClient , esURL ))
218
- }
219
-
220
- if * esExportDataStream {
221
- prometheus .MustRegister (collector .NewDataStream (logger , httpClient , esURL ))
222
- }
223
-
224
- if * esExportIndicesSettings {
225
- prometheus .MustRegister (collector .NewIndicesSettings (logger , httpClient , esURL ))
226
- }
227
-
228
- if * esExportIndicesMappings {
229
- prometheus .MustRegister (collector .NewIndicesMappings (logger , httpClient , esURL ))
230
- }
231
-
232
- if * esExportILM {
233
- prometheus .MustRegister (collector .NewIlmStatus (logger , httpClient , esURL ))
234
- prometheus .MustRegister (collector .NewIlmIndicies (logger , httpClient , esURL ))
235
- }
146
+ clusterRetrieverMap := make (map [string ]* clusterinfo.Retriever )
236
147
237
148
// Create a context that is cancelled on SIGKILL or SIGINT.
238
149
ctx , cancel := signal .NotifyContext (context .Background (), os .Interrupt , os .Kill )
239
150
defer cancel ()
240
151
241
- // start the cluster info retriever
242
- switch runErr := clusterInfoRetriever .Run (ctx ); runErr {
243
- case nil :
244
- level .Info (logger ).Log (
245
- "msg" , "started cluster info retriever" ,
246
- "interval" , (* esClusterInfoInterval ).String (),
247
- )
248
- case clusterinfo .ErrInitialCallTimeout :
249
- level .Info (logger ).Log ("msg" , "initial cluster info call timed out" )
250
- default :
251
- level .Error (logger ).Log ("msg" , "failed to run cluster info retriever" , "err" , err )
252
- os .Exit (1 )
253
- }
254
-
255
- // register cluster info retriever as prometheus collector
256
- prometheus .MustRegister (clusterInfoRetriever )
152
+ probePath := "/probe"
257
153
258
154
http .Handle (* metricsPath , promhttp .Handler ())
259
155
if * metricsPath != "/" && * metricsPath != "" {
@@ -263,8 +159,14 @@ func main() {
263
159
Version : version .Info (),
264
160
Links : []web.LandingLinks {
265
161
{
266
- Address : * metricsPath ,
267
- Text : "Metrics" ,
162
+ Address : * metricsPath ,
163
+ Text : "Metrics" ,
164
+ Description : "Metrics endpoint exposing elasticsearch-exporter metrics in the Prometheus exposition format." ,
165
+ },
166
+ {
167
+ Address : probePath ,
168
+ Text : "Probe" ,
169
+ Description : "Probe endpoint for testing the exporter against a specific Elasticsearch instance." ,
268
170
},
269
171
},
270
172
}
@@ -276,6 +178,150 @@ func main() {
276
178
http .Handle ("/" , landingPage )
277
179
}
278
180
181
+ http .HandleFunc ("/probe" , func (w http.ResponseWriter , r * http.Request ) {
182
+ params := r .URL .Query ()
183
+ target := params .Get ("target" )
184
+
185
+ if target != "" {
186
+ targetURL , err := url .Parse (target )
187
+ if err != nil {
188
+ http .Error (w , "invalid target" , http .StatusBadRequest )
189
+ return
190
+ }
191
+
192
+ targetUsername := os .Getenv ("ES_USERNAME" )
193
+ targetPassword := os .Getenv ("ES_PASSWORD" )
194
+
195
+ authModule := params .Get ("auth_module" )
196
+ if authModule != "" {
197
+ targetUsername = os .Getenv (fmt .Sprintf ("ES_%s_USERNAME" , authModule ))
198
+ targetPassword = os .Getenv (fmt .Sprintf ("ES_%s_PASSWORD" , authModule ))
199
+ }
200
+
201
+ if targetUsername != "" && targetPassword != "" {
202
+ targetURL .User = url .UserPassword (targetUsername , targetPassword )
203
+ }
204
+
205
+ esURL = targetURL
206
+ }
207
+
208
+ registry := prometheus .NewRegistry ()
209
+ // returns nil if not provided and falls back to simple TCP.
210
+ tlsConfig := createTLSConfig (* esCA , * esClientCert , * esClientPrivateKey , * esInsecureSkipVerify )
211
+
212
+ var httpTransport http.RoundTripper
213
+
214
+ httpTransport = & http.Transport {
215
+ TLSClientConfig : tlsConfig ,
216
+ Proxy : http .ProxyFromEnvironment ,
217
+ }
218
+
219
+ esAPIKey := os .Getenv ("ES_API_KEY" )
220
+
221
+ if esAPIKey != "" {
222
+ httpTransport = & transportWithAPIKey {
223
+ underlyingTransport : httpTransport ,
224
+ apiKey : esAPIKey ,
225
+ }
226
+ }
227
+
228
+ httpClient := & http.Client {
229
+ Timeout : * esTimeout ,
230
+ Transport : httpTransport ,
231
+ }
232
+
233
+ if * awsRegion != "" {
234
+ httpClient .Transport , err = roundtripper .NewAWSSigningTransport (httpTransport , * awsRegion , * awsRoleArn , logger )
235
+ if err != nil {
236
+ level .Error (logger ).Log ("msg" , "failed to create AWS transport" , "err" , err )
237
+ os .Exit (1 )
238
+ }
239
+ }
240
+
241
+ // version metric
242
+ registry .MustRegister (version .NewCollector (name ))
243
+
244
+ // create the exporter
245
+ exporter , err := collector .NewElasticsearchCollector (
246
+ logger ,
247
+ []string {},
248
+ collector .WithElasticsearchURL (esURL ),
249
+ collector .WithHTTPClient (httpClient ),
250
+ )
251
+ if err != nil {
252
+ level .Error (logger ).Log ("msg" , "failed to create Elasticsearch collector" , "err" , err )
253
+ os .Exit (1 )
254
+ }
255
+ registry .MustRegister (exporter )
256
+
257
+ // TODO(@sysadmind): Remove this when we have a better way to get the cluster name to down stream collectors.
258
+ // cluster info retriever
259
+
260
+ clusterInfoRetriever , ok := clusterRetrieverMap [target ]
261
+ if ! ok {
262
+ clusterInfoRetriever = clusterinfo .New (logger , httpClient , esURL , * esClusterInfoInterval )
263
+ clusterRetrieverMap [target ] = clusterInfoRetriever
264
+
265
+ // start the cluster info retriever
266
+ switch runErr := clusterInfoRetriever .Run (ctx ); runErr {
267
+ case nil :
268
+ level .Info (logger ).Log (
269
+ "msg" , fmt .Sprintf ("[%s]started cluster info retriever" , esURL .Host ),
270
+ "interval" , (* esClusterInfoInterval ).String (),
271
+ )
272
+ case clusterinfo .ErrInitialCallTimeout :
273
+ level .Info (logger ).Log ("msg" , fmt .Sprintf ("[%s]initial cluster info call timed out" , esURL .Host ))
274
+ default :
275
+ level .Error (logger ).Log ("msg" , fmt .Sprintf ("[%s]failed to run cluster info retriever" , esURL .Host ), "err" , err )
276
+ }
277
+ }
278
+
279
+ registry .MustRegister (collector .NewClusterHealth (logger , httpClient , esURL ))
280
+ registry .MustRegister (collector .NewNodes (logger , httpClient , esURL , * esAllNodes , * esNode ))
281
+
282
+ if * esExportIndices || * esExportShards {
283
+ sC := collector .NewShards (logger , httpClient , esURL )
284
+ prometheus .MustRegister (sC )
285
+ iC := collector .NewIndices (logger , httpClient , esURL , * esExportShards , * esExportIndexAliases )
286
+ prometheus .MustRegister (iC )
287
+ if registerErr := clusterInfoRetriever .RegisterConsumer (iC ); registerErr != nil {
288
+ level .Error (logger ).Log ("msg" , "failed to register indices collector in cluster info" )
289
+ os .Exit (1 )
290
+ }
291
+ if registerErr := clusterInfoRetriever .RegisterConsumer (sC ); registerErr != nil {
292
+ level .Error (logger ).Log ("msg" , "failed to register shards collector in cluster info" )
293
+ os .Exit (1 )
294
+ }
295
+ }
296
+
297
+ if * esExportSLM {
298
+ registry .MustRegister (collector .NewSLM (logger , httpClient , esURL ))
299
+ }
300
+
301
+ if * esExportDataStream {
302
+ registry .MustRegister (collector .NewDataStream (logger , httpClient , esURL ))
303
+ }
304
+
305
+ if * esExportIndicesSettings {
306
+ registry .MustRegister (collector .NewIndicesSettings (logger , httpClient , esURL ))
307
+ }
308
+
309
+ if * esExportIndicesMappings {
310
+ registry .MustRegister (collector .NewIndicesMappings (logger , httpClient , esURL ))
311
+ }
312
+
313
+ if * esExportILM {
314
+ registry .MustRegister (collector .NewIlmStatus (logger , httpClient , esURL ))
315
+ registry .MustRegister (collector .NewIlmIndicies (logger , httpClient , esURL ))
316
+ }
317
+
318
+ // register cluster info retriever as prometheus collector
319
+ registry .MustRegister (clusterInfoRetriever )
320
+
321
+ h := promhttp .HandlerFor (registry , promhttp.HandlerOpts {})
322
+ h .ServeHTTP (w , r )
323
+ })
324
+
279
325
// health endpoint
280
326
http .HandleFunc ("/healthz" , func (w http.ResponseWriter , r * http.Request ) {
281
327
http .Error (w , http .StatusText (http .StatusOK ), http .StatusOK )
0 commit comments