22
33import io .prometheus .client .CollectorRegistry ;
44import io .prometheus .client .MetricNameFilter ;
5+ import io .prometheus .client .Predicate ;
56import io .prometheus .client .exporter .common .TextFormat ;
67
78import java .io .ByteArrayOutputStream ;
1112import java .net .InetSocketAddress ;
1213import java .net .URLDecoder ;
1314import java .nio .charset .Charset ;
14- import java .util .ArrayList ;
15- import java .util .Collection ;
16- import java .util .Collections ;
1715import java .util .HashSet ;
1816import java .util .List ;
1917import java .util .Set ;
@@ -65,16 +63,16 @@ protected ByteArrayOutputStream initialValue()
6563 public static class HTTPMetricHandler implements HttpHandler {
6664 private final CollectorRegistry registry ;
6765 private final LocalByteArray response = new LocalByteArray ();
68- private final Config config ;
66+ private final Predicate < String > metricNameFilter ;
6967 private final static String HEALTHY_RESPONSE = "Exporter is Healthy." ;
7068
7169 HTTPMetricHandler (CollectorRegistry registry ) {
7270 this (registry , null );
7371 }
7472
75- HTTPMetricHandler (CollectorRegistry registry , Config config ) {
73+ HTTPMetricHandler (CollectorRegistry registry , Predicate < String > metricNameFilter ) {
7674 this .registry = registry ;
77- this .config = config == null ? new Config () : config ;
75+ this .metricNameFilter = metricNameFilter ;
7876 }
7977
8078 @ Override
@@ -90,12 +88,12 @@ public void handle(HttpExchange t) throws IOException {
9088 } else {
9189 String contentType = TextFormat .chooseContentType (t .getRequestHeaders ().getFirst ("Accept" ));
9290 t .getResponseHeaders ().set ("Content-Type" , contentType );
93- MetricNameFilter filter = new MetricNameFilter . Builder ()
94- . includeNames ( parseQuery ( query ))
95- . includePrefixes ( config . getIncludedPrefixes ())
96- . excludePrefixes ( config . getExcludedPrefixes ())
97- . build ( );
98- TextFormat . writeFormat ( contentType , osw , registry . filteredMetricFamilySamples ( filter ));
91+ Predicate < String > filter = composeFilter ( query );
92+ if ( filter == null ) {
93+ TextFormat . writeFormat ( contentType , osw , registry . metricFamilySamples ());
94+ } else {
95+ TextFormat . writeFormat ( contentType , osw , registry . filteredMetricFamilySamples ( filter ) );
96+ }
9997 }
10098
10199 osw .close ();
@@ -118,6 +116,21 @@ public void handle(HttpExchange t) throws IOException {
118116 t .close ();
119117 }
120118
119+ private Predicate <String > composeFilter (String query ) throws IOException {
120+ Predicate <String > result = this .metricNameFilter ;
121+ Set <String > includedNames = parseQuery (query );
122+ if (!includedNames .isEmpty ()) {
123+ MetricNameFilter filterFromQueryParams = new MetricNameFilter .Builder ()
124+ .includePrefixes (includedNames )
125+ .build ();
126+ if (result == null ) {
127+ result = filterFromQueryParams ;
128+ } else {
129+ result = filterFromQueryParams .and (result );
130+ }
131+ }
132+ return result ;
133+ }
121134 }
122135
123136 protected static boolean shouldUseCompression (HttpExchange exchange ) {
@@ -179,50 +192,6 @@ static ThreadFactory defaultThreadFactory(boolean daemon) {
179192 protected final HttpServer server ;
180193 protected final ExecutorService executorService ;
181194
182- /**
183- * Configure the HTTPServer to include / exclude metrics by name prefix.
184- */
185- public static class Config {
186-
187- private final Collection <String > includedPrefixes ;
188- private final Collection <String > excludedPrefixes ;
189-
190- /**
191- * Empty config means nothing is filtered; all metrics are exported.
192- */
193- public Config () {
194- includedPrefixes = Collections .emptyList ();
195- excludedPrefixes = Collections .emptyList ();
196- }
197-
198- /**
199- * If {@code includedNamePrefixes} is not empty, only metrics with a name starting with one of these
200- * prefixes will be exported. If {@code excludedNamePrefixes} is not empty, metrics with a name
201- * starting with one of these prefixes will not be exported. If both parameters are not empty, metrics
202- * must match both criteria in order to be exported.
203- */
204- public Config (Collection <String > includedNamePrefixes , Collection <String > excludedNamePrefixes ) {
205- this .includedPrefixes = unmodifiableCopy (includedNamePrefixes );
206- this .excludedPrefixes = unmodifiableCopy (excludedNamePrefixes );
207- }
208-
209- private Collection <String > unmodifiableCopy (Collection <String > collection ) {
210- if (collection == null ) {
211- return Collections .emptyList ();
212- } else {
213- return Collections .unmodifiableCollection (new ArrayList <String >(collection ));
214- }
215- }
216-
217- public Collection <String > getIncludedPrefixes () {
218- return includedPrefixes ;
219- }
220-
221- public Collection <String > getExcludedPrefixes () {
222- return excludedPrefixes ;
223- }
224- }
225-
226195 /**
227196 * Start an HTTP server serving the default Prometheus registry using non-daemon threads.
228197 */
@@ -231,11 +200,11 @@ public HTTPServer(int port) throws IOException {
231200 }
232201
233202 /**
234- * Like {@link #HTTPServer(int)}, but with an additional {@link Config } parameter to configure
235- * which metrics should be exported.
203+ * Like {@link #HTTPServer(int)}, but with an additional {@code metricNameFilter } parameter
204+ * to configure which metrics should be exported.
236205 */
237- public HTTPServer (int port , Config config ) throws IOException {
238- this (port , false , config );
206+ public HTTPServer (int port , Predicate < String > metricNameFilter ) throws IOException {
207+ this (port , false , metricNameFilter );
239208 }
240209
241210 /**
@@ -246,11 +215,11 @@ public HTTPServer(int port, boolean daemon) throws IOException {
246215 }
247216
248217 /**
249- * Like {@link #HTTPServer(int, boolean)}, but with an additional {@link Config }
218+ * Like {@link #HTTPServer(int, boolean)}, but with an additional {@code metricNameFilter }
250219 * parameter to configure which metrics should be exported.
251220 */
252- public HTTPServer (int port , boolean daemon , Config config ) throws IOException {
253- this (new InetSocketAddress (port ), CollectorRegistry .defaultRegistry , daemon , config );
221+ public HTTPServer (int port , boolean daemon , Predicate < String > metricNameFilter ) throws IOException {
222+ this (new InetSocketAddress (port ), CollectorRegistry .defaultRegistry , daemon , metricNameFilter );
254223 }
255224
256225 /**
@@ -261,11 +230,11 @@ public HTTPServer(String host, int port) throws IOException {
261230 }
262231
263232 /**
264- * Like {@link #HTTPServer(String, int)}, but with an additional {@link Config }
233+ * Like {@link #HTTPServer(String, int)}, but with an additional {@code metricNameFilter }
265234 * parameter to configure which metrics should be exported.
266235 */
267- public HTTPServer (String host , int port , Config config ) throws IOException {
268- this (host , port , false , config );
236+ public HTTPServer (String host , int port , Predicate < String > metricNameFilter ) throws IOException {
237+ this (host , port , false , metricNameFilter );
269238 }
270239
271240 /**
@@ -276,11 +245,11 @@ public HTTPServer(String host, int port, boolean daemon) throws IOException {
276245 }
277246
278247 /**
279- * Like {@link #HTTPServer(String, int, boolean)}, but with an additional {@link Config }
248+ * Like {@link #HTTPServer(String, int, boolean)}, but with an additional {@code metricNameFilter }
280249 * parameter to configure which metrics should be exported.
281250 */
282- public HTTPServer (String host , int port , boolean daemon , Config config ) throws IOException {
283- this (new InetSocketAddress (host , port ), CollectorRegistry .defaultRegistry , daemon , config );
251+ public HTTPServer (String host , int port , boolean daemon , Predicate < String > metricNameFilter ) throws IOException {
252+ this (new InetSocketAddress (host , port ), CollectorRegistry .defaultRegistry , daemon , metricNameFilter );
284253 }
285254
286255 /**
@@ -291,11 +260,11 @@ public HTTPServer(InetSocketAddress addr, CollectorRegistry registry) throws IOE
291260 }
292261
293262 /**
294- * Like {@link #HTTPServer(InetSocketAddress, CollectorRegistry)}, but with an additional {@link Config }
263+ * Like {@link #HTTPServer(InetSocketAddress, CollectorRegistry)}, but with an additional {@code metricNameFilter }
295264 * parameter to configure which metrics should be exported.
296265 */
297- public HTTPServer (InetSocketAddress addr , CollectorRegistry registry , Config config ) throws IOException {
298- this (addr , registry , false , config );
266+ public HTTPServer (InetSocketAddress addr , CollectorRegistry registry , Predicate < String > metricNameFilter ) throws IOException {
267+ this (addr , registry , false , metricNameFilter );
299268 }
300269
301270 /**
@@ -306,11 +275,11 @@ public HTTPServer(InetSocketAddress addr, CollectorRegistry registry, boolean da
306275 }
307276
308277 /**
309- * Like {@link #HTTPServer(InetSocketAddress, CollectorRegistry, boolean)}, but with an additional {@link Config}
310- * parameter to configure which metrics should be exported.
278+ * Like {@link #HTTPServer(InetSocketAddress, CollectorRegistry, boolean)}, but with an additional
279+ * {@code metricNameFilter} parameter to configure which metrics should be exported.
311280 */
312- public HTTPServer (InetSocketAddress addr , CollectorRegistry registry , boolean daemon , Config config ) throws IOException {
313- this (HttpServer .create (addr , 3 ), registry , daemon , config );
281+ public HTTPServer (InetSocketAddress addr , CollectorRegistry registry , boolean daemon , Predicate < String > metricNameFilter ) throws IOException {
282+ this (HttpServer .create (addr , 3 ), registry , daemon , metricNameFilter );
314283 }
315284
316285 /**
@@ -323,15 +292,15 @@ public HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean dae
323292
324293
325294 /**
326- * Like {@link #HTTPServer(HttpServer, CollectorRegistry, boolean)}, but with an additional {@link Config }
295+ * Like {@link #HTTPServer(HttpServer, CollectorRegistry, boolean)}, but with an additional {@code metricNameFilter }
327296 * parameter to configure which metrics should be exported.
328297 */
329- public HTTPServer (HttpServer httpServer , CollectorRegistry registry , boolean daemon , Config config ) throws IOException {
298+ public HTTPServer (HttpServer httpServer , CollectorRegistry registry , boolean daemon , Predicate < String > metricNameFilter ) throws IOException {
330299 if (httpServer .getAddress () == null )
331300 throw new IllegalArgumentException ("HttpServer hasn't been bound to an address" );
332301
333302 server = httpServer ;
334- HttpHandler mHandler = new HTTPMetricHandler (registry , config );
303+ HttpHandler mHandler = new HTTPMetricHandler (registry , metricNameFilter );
335304 server .createContext ("/" , mHandler );
336305 server .createContext ("/metrics" , mHandler );
337306 server .createContext ("/-/healthy" , mHandler );
0 commit comments