Skip to content

Commit 5d488ec

Browse files
committed
Add HTTPServer.Config for including/excluding name prefixes
Signed-off-by: Fabian Stäber <[email protected]>
1 parent e65218b commit 5d488ec

File tree

1 file changed

+141
-38
lines changed
  • simpleclient_httpserver/src/main/java/io/prometheus/client/exporter

1 file changed

+141
-38
lines changed

simpleclient_httpserver/src/main/java/io/prometheus/client/exporter/HTTPServer.java

Lines changed: 141 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
import java.net.InetSocketAddress;
1212
import java.net.URLDecoder;
1313
import java.nio.charset.Charset;
14+
import java.util.ArrayList;
15+
import java.util.Collection;
16+
import java.util.Collections;
1417
import java.util.HashSet;
1518
import java.util.List;
1619
import java.util.Set;
@@ -62,16 +65,16 @@ protected ByteArrayOutputStream initialValue()
6265
public static class HTTPMetricHandler implements HttpHandler {
6366
private final CollectorRegistry registry;
6467
private final LocalByteArray response = new LocalByteArray();
65-
private final MetricNameFilter filter;
68+
private final Config config;
6669
private final static String HEALTHY_RESPONSE = "Exporter is Healthy.";
6770

6871
HTTPMetricHandler(CollectorRegistry registry) {
6972
this(registry, null);
7073
}
7174

72-
HTTPMetricHandler(CollectorRegistry registry, MetricNameFilter filter) {
75+
HTTPMetricHandler(CollectorRegistry registry, Config config) {
7376
this.registry = registry;
74-
this.filter = filter;
77+
this.config = config == null ? new Config() : config;
7578
}
7679

7780
@Override
@@ -87,9 +90,12 @@ public void handle(HttpExchange t) throws IOException {
8790
} else {
8891
String contentType = TextFormat.chooseContentType(t.getRequestHeaders().getFirst("Accept"));
8992
t.getResponseHeaders().set("Content-Type", contentType);
90-
MetricNameFilter.Builder filterBuilder = filter == null ? new MetricNameFilter.Builder() : filter.toBuilder();
91-
TextFormat.writeFormat(contentType, osw,
92-
registry.filteredMetricFamilySamples(filterBuilder.includeNames(parseQuery(query)).build()));
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));
9399
}
94100

95101
osw.close();
@@ -174,67 +180,164 @@ static ThreadFactory defaultThreadFactory(boolean daemon) {
174180
protected final ExecutorService executorService;
175181

176182
/**
177-
* Start a HTTP server serving Prometheus metrics from the given registry using the given {@link HttpServer}.
178-
* The {@code httpServer} is expected to already be bound to an address
183+
* Configure the HTTPServer to include / exclude metrics by name prefix.
179184
*/
180-
public HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon) throws IOException {
181-
this(httpServer, registry, null, daemon);
182-
}
185+
public static class Config {
183186

184-
public HTTPServer(HttpServer httpServer, CollectorRegistry registry, MetricNameFilter filter, boolean daemon) throws IOException {
185-
if (httpServer.getAddress() == null)
186-
throw new IllegalArgumentException("HttpServer hasn't been bound to an address");
187+
private final Collection<String> includedPrefixes;
188+
private final Collection<String> excludedPrefixes;
187189

188-
server = httpServer;
189-
HttpHandler mHandler = new HTTPMetricHandler(registry, filter);
190-
server.createContext("/", mHandler);
191-
server.createContext("/metrics", mHandler);
192-
server.createContext("/-/healthy", mHandler);
193-
executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon));
194-
server.setExecutor(executorService);
195-
start(daemon);
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+
}
196224
}
197225

198226
/**
199-
* Start a HTTP server serving Prometheus metrics from the given registry.
227+
* Start an HTTP server serving the default Prometheus registry using non-daemon threads.
200228
*/
201-
public HTTPServer(InetSocketAddress addr, CollectorRegistry registry, boolean daemon) throws IOException {
202-
this(HttpServer.create(addr, 3), registry, daemon);
229+
public HTTPServer(int port) throws IOException {
230+
this(port, null);
203231
}
204232

205233
/**
206-
* Start a HTTP server serving Prometheus metrics from the given registry using non-daemon threads.
234+
* Like {@link #HTTPServer(int)}, but with an additional {@link Config} parameter to configure
235+
* which metrics should be exported.
207236
*/
208-
public HTTPServer(InetSocketAddress addr, CollectorRegistry registry) throws IOException {
209-
this(addr, registry, false);
237+
public HTTPServer(int port, Config config) throws IOException {
238+
this(port, false, config);
210239
}
211240

212241
/**
213-
* Start a HTTP server serving the default Prometheus registry.
242+
* Start an HTTP server serving the default Prometheus registry.
214243
*/
215244
public HTTPServer(int port, boolean daemon) throws IOException {
216-
this(new InetSocketAddress(port), CollectorRegistry.defaultRegistry, daemon);
245+
this(port, daemon, null);
217246
}
218247

219248
/**
220-
* Start a HTTP server serving the default Prometheus registry using non-daemon threads.
249+
* Like {@link #HTTPServer(int, boolean)}, but with an additional {@link Config}
250+
* parameter to configure which metrics should be exported.
221251
*/
222-
public HTTPServer(int port) throws IOException {
223-
this(port, false);
252+
public HTTPServer(int port, boolean daemon, Config config) throws IOException {
253+
this(new InetSocketAddress(port), CollectorRegistry.defaultRegistry, daemon, config);
224254
}
225255

226256
/**
227-
* Start a HTTP server serving the default Prometheus registry.
257+
* Start an HTTP server serving the default Prometheus registry using non-daemon threads.
258+
*/
259+
public HTTPServer(String host, int port) throws IOException {
260+
this(host, port, null);
261+
}
262+
263+
/**
264+
* Like {@link #HTTPServer(String, int)}, but with an additional {@link Config}
265+
* parameter to configure which metrics should be exported.
266+
*/
267+
public HTTPServer(String host, int port, Config config) throws IOException {
268+
this(host, port, false, config);
269+
}
270+
271+
/**
272+
* Start an HTTP server serving the default Prometheus registry.
228273
*/
229274
public HTTPServer(String host, int port, boolean daemon) throws IOException {
230-
this(new InetSocketAddress(host, port), CollectorRegistry.defaultRegistry, daemon);
275+
this(host, port, daemon, null);
231276
}
232277

233278
/**
234-
* Start a HTTP server serving the default Prometheus registry using non-daemon threads.
279+
* Like {@link #HTTPServer(String, int, boolean)}, but with an additional {@link Config}
280+
* parameter to configure which metrics should be exported.
235281
*/
236-
public HTTPServer(String host, int port) throws IOException {
237-
this(new InetSocketAddress(host, port), CollectorRegistry.defaultRegistry, false);
282+
public HTTPServer(String host, int port, boolean daemon, Config config) throws IOException {
283+
this(new InetSocketAddress(host, port), CollectorRegistry.defaultRegistry, daemon, config);
284+
}
285+
286+
/**
287+
* Start an HTTP server serving Prometheus metrics from the given registry using non-daemon threads.
288+
*/
289+
public HTTPServer(InetSocketAddress addr, CollectorRegistry registry) throws IOException {
290+
this(addr, registry, null);
291+
}
292+
293+
/**
294+
* Like {@link #HTTPServer(InetSocketAddress, CollectorRegistry)}, but with an additional {@link Config}
295+
* parameter to configure which metrics should be exported.
296+
*/
297+
public HTTPServer(InetSocketAddress addr, CollectorRegistry registry, Config config) throws IOException {
298+
this(addr, registry, false, config);
299+
}
300+
301+
/**
302+
* Start an HTTP server serving Prometheus metrics from the given registry.
303+
*/
304+
public HTTPServer(InetSocketAddress addr, CollectorRegistry registry, boolean daemon) throws IOException {
305+
this(addr, registry, daemon, null);
306+
}
307+
308+
/**
309+
* Like {@link #HTTPServer(InetSocketAddress, CollectorRegistry, boolean)}, but with an additional {@link Config}
310+
* parameter to configure which metrics should be exported.
311+
*/
312+
public HTTPServer(InetSocketAddress addr, CollectorRegistry registry, boolean daemon, Config config) throws IOException {
313+
this(HttpServer.create(addr, 3), registry, daemon, config);
314+
}
315+
316+
/**
317+
* Start an HTTP server serving Prometheus metrics from the given registry using the given {@link HttpServer}.
318+
* The {@code httpServer} is expected to already be bound to an address
319+
*/
320+
public HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon) throws IOException {
321+
this(httpServer, registry, daemon, null);
322+
}
323+
324+
325+
/**
326+
* Like {@link #HTTPServer(HttpServer, CollectorRegistry, boolean)}, but with an additional {@link Config}
327+
* parameter to configure which metrics should be exported.
328+
*/
329+
public HTTPServer(HttpServer httpServer, CollectorRegistry registry, boolean daemon, Config config) throws IOException {
330+
if (httpServer.getAddress() == null)
331+
throw new IllegalArgumentException("HttpServer hasn't been bound to an address");
332+
333+
server = httpServer;
334+
HttpHandler mHandler = new HTTPMetricHandler(registry, config);
335+
server.createContext("/", mHandler);
336+
server.createContext("/metrics", mHandler);
337+
server.createContext("/-/healthy", mHandler);
338+
executorService = Executors.newFixedThreadPool(5, NamedDaemonThreadFactory.defaultThreadFactory(daemon));
339+
server.setExecutor(executorService);
340+
start(daemon);
238341
}
239342

240343
/**

0 commit comments

Comments
 (0)