14
14
package main
15
15
16
16
import (
17
+ "fmt"
17
18
"net/http"
18
19
"os"
19
20
20
21
"github.com/go-kit/log"
21
22
"github.com/go-kit/log/level"
22
23
"github.com/prometheus-community/postgres_exporter/collector"
23
24
"github.com/prometheus/client_golang/prometheus"
25
+ "github.com/prometheus/client_golang/prometheus/collectors"
24
26
"github.com/prometheus/client_golang/prometheus/promhttp"
25
27
"github.com/prometheus/common/promlog"
26
28
"github.com/prometheus/common/promlog/flag"
@@ -113,11 +115,12 @@ func main() {
113
115
exporter .servers .Close ()
114
116
}()
115
117
116
- prometheus .MustRegister (version .NewCollector (exporterName ))
118
+ versionCollector := version .NewCollector (exporterName )
119
+ prometheus .MustRegister (versionCollector )
117
120
118
121
prometheus .MustRegister (exporter )
119
122
120
- cleanup := initializePerconaExporters (dsn , opts )
123
+ cleanup , hr , mr , lr := initializePerconaExporters (dsn , opts )
121
124
defer cleanup ()
122
125
123
126
pe , err := collector .NewPostgresCollector (
@@ -131,7 +134,21 @@ func main() {
131
134
}
132
135
prometheus .MustRegister (pe )
133
136
134
- http .Handle (* metricPath , promhttp .Handler ())
137
+ psCollector := collectors .NewProcessCollector (collectors.ProcessCollectorOpts {})
138
+ goCollector := collectors .NewGoCollector ()
139
+
140
+ promHandler := newHandler (map [string ]prometheus.Collector {
141
+ "exporter" : exporter ,
142
+ "custom_query.hr" : hr ,
143
+ "custom_query.mr" : mr ,
144
+ "custom_query.lr" : lr ,
145
+ "standard.process" : psCollector ,
146
+ "standard.go" : goCollector ,
147
+ "version" : versionCollector ,
148
+ })
149
+
150
+ http .Handle (* metricPath , promHandler )
151
+
135
152
http .HandleFunc ("/" , func (w http.ResponseWriter , r * http.Request ) {
136
153
w .Header ().Set ("Content-Type" , "text/html; charset=UTF-8" ) // nolint: errcheck
137
154
w .Write (landingPage ) // nolint: errcheck
@@ -152,3 +169,80 @@ func main() {
152
169
os .Exit (1 )
153
170
}
154
171
}
172
+
173
+ // handler wraps an unfiltered http.Handler but uses a filtered handler,
174
+ // created on the fly, if filtering is requested. Create instances with
175
+ // newHandler. It used for collectors filtering.
176
+ type handler struct {
177
+ unfilteredHandler http.Handler
178
+ collectors map [string ]prometheus.Collector
179
+ }
180
+
181
+ func newHandler (collectors map [string ]prometheus.Collector ) * handler {
182
+ h := & handler {collectors : collectors }
183
+
184
+ innerHandler , err := h .innerHandler ()
185
+ if err != nil {
186
+ level .Error (logger ).Log ("msg" , "Couldn't create metrics handler" , "error" , err )
187
+ os .Exit (1 )
188
+ }
189
+
190
+ h .unfilteredHandler = innerHandler
191
+ return h
192
+ }
193
+
194
+ // ServeHTTP implements http.Handler.
195
+ func (h * handler ) ServeHTTP (w http.ResponseWriter , r * http.Request ) {
196
+ filters := r .URL .Query ()["collect[]" ]
197
+ level .Debug (logger ).Log ("msg" , "Collect query" , "filters" , filters )
198
+
199
+ if len (filters ) == 0 {
200
+ // No filters, use the prepared unfiltered handler.
201
+ h .unfilteredHandler .ServeHTTP (w , r )
202
+ return
203
+ }
204
+
205
+ filteredHandler , err := h .innerHandler (filters ... )
206
+ if err != nil {
207
+ level .Warn (logger ).Log ("msg" , "Couldn't create filtered metrics handler" , "error" , err )
208
+ w .WriteHeader (http .StatusBadRequest )
209
+ w .Write ([]byte (fmt .Sprintf ("Couldn't create filtered metrics handler: %s" , err )))
210
+ return
211
+ }
212
+
213
+ filteredHandler .ServeHTTP (w , r )
214
+ }
215
+
216
+ func (h * handler ) innerHandler (filters ... string ) (http.Handler , error ) {
217
+ registry := prometheus .NewRegistry ()
218
+
219
+ // register all collectors by default.
220
+ if len (filters ) == 0 {
221
+ for name , c := range h .collectors {
222
+ if err := registry .Register (c ); err != nil {
223
+ return nil , err
224
+ }
225
+ level .Debug (logger ).Log ("msg" , "Collector was registered" , "collector" , name )
226
+ }
227
+ }
228
+
229
+ // register only filtered collectors.
230
+ for _ , name := range filters {
231
+ if c , ok := h .collectors [name ]; ok {
232
+ if err := registry .Register (c ); err != nil {
233
+ return nil , err
234
+ }
235
+ level .Debug (logger ).Log ("msg" , "Collector was registered" , "collector" , name )
236
+ }
237
+ }
238
+
239
+ handler := promhttp .HandlerFor (
240
+ registry ,
241
+ promhttp.HandlerOpts {
242
+ //ErrorLog: log.NewNopLogger() .NewErrorLogger(),
243
+ ErrorHandling : promhttp .ContinueOnError ,
244
+ },
245
+ )
246
+
247
+ return handler , nil
248
+ }
0 commit comments