Skip to content

Commit 8143f69

Browse files
committed
Add escaping scheme to ExporterPushgatewayProperties
Signed-off-by: Federico Torres <[email protected]>
1 parent 891d28d commit 8143f69

File tree

3 files changed

+65
-5
lines changed

3 files changed

+65
-5
lines changed

prometheus-metrics-config/src/main/java/io/prometheus/metrics/config/ExporterPushgatewayProperties.java

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@ public class ExporterPushgatewayProperties {
77
private static final String ADDRESS = "address";
88
private static final String JOB = "job";
99
private static final String SCHEME = "scheme";
10+
private static final String ESCAPING_SCHEME = "escapingScheme";
1011
private static final String PREFIX = "io.prometheus.exporter.pushgateway";
1112
private final String scheme;
1213
private final String address;
1314
private final String job;
15+
private final String escapingScheme;
1416

15-
private ExporterPushgatewayProperties(String address, String job, String scheme) {
17+
private ExporterPushgatewayProperties(String address, String job, String scheme, String escapingScheme) {
1618
this.address = address;
1719
this.job = job;
1820
this.scheme = scheme;
21+
this.escapingScheme = escapingScheme;
1922
}
2023

2124
/** Address of the Pushgateway in the form {@code host:port}. Default is {@code localhost:9091} */
@@ -39,6 +42,14 @@ public String getScheme() {
3942
return scheme;
4043
}
4144

45+
/**
46+
* Escaping scheme to be used when pushing metric data to the pushgateway.
47+
* Valid values: "no-escaping", "values", "underscores", "dots". Default is "no-escaping".
48+
*/
49+
public String getEscapingScheme() {
50+
return escapingScheme;
51+
}
52+
4253
/**
4354
* Note that this will remove entries from {@code properties}. This is because we want to know if
4455
* there are unused properties remaining after all properties have been loaded.
@@ -48,6 +59,8 @@ static ExporterPushgatewayProperties load(Map<Object, Object> properties)
4859
String address = Util.loadString(PREFIX + "." + ADDRESS, properties);
4960
String job = Util.loadString(PREFIX + "." + JOB, properties);
5061
String scheme = Util.loadString(PREFIX + "." + SCHEME, properties);
62+
String escapingScheme = Util.loadString(PREFIX + "." + ESCAPING_SCHEME, properties);
63+
5164
if (scheme != null) {
5265
if (!scheme.equals("http") && !scheme.equals("https")) {
5366
throw new PrometheusPropertiesException(
@@ -56,6 +69,17 @@ static ExporterPushgatewayProperties load(Map<Object, Object> properties)
5669
PREFIX, SCHEME, scheme));
5770
}
5871
}
59-
return new ExporterPushgatewayProperties(address, job, scheme);
72+
73+
if (escapingScheme != null) {
74+
if (!escapingScheme.equals("no-escaping") && !escapingScheme.equals("values")
75+
&& !escapingScheme.equals("underscores") && !escapingScheme.equals("dots")) {
76+
throw new PrometheusPropertiesException(
77+
String.format(
78+
"%s.%s: Illegal value. Expecting 'no-escaping', 'values', 'underscores', or 'dots'. Found: %s",
79+
PREFIX, ESCAPING_SCHEME, escapingScheme));
80+
}
81+
}
82+
83+
return new ExporterPushgatewayProperties(address, job, scheme, escapingScheme);
6084
}
6185
}

prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,22 @@ public class PushGateway {
8787
private final Map<String, String> requestHeaders;
8888
private final PrometheusRegistry registry;
8989
private final HttpConnectionFactory connectionFactory;
90+
private final EscapingScheme escapingScheme;
9091

9192
private PushGateway(
9293
PrometheusRegistry registry,
9394
Format format,
9495
URL url,
9596
HttpConnectionFactory connectionFactory,
9697
Map<String, String> requestHeaders,
97-
boolean prometheusTimestampsInMs) {
98+
boolean prometheusTimestampsInMs,
99+
EscapingScheme escapingScheme) {
98100
this.registry = registry;
99101
this.url = url;
100102
this.requestHeaders = Collections.unmodifiableMap(new HashMap<>(requestHeaders));
101103
this.connectionFactory = connectionFactory;
102104
this.prometheusTimestampsInMs = prometheusTimestampsInMs;
105+
this.escapingScheme = escapingScheme;
103106
writer = getWriter(format);
104107
if (!writer.isAvailable()) {
105108
throw new RuntimeException(writer.getClass() + " is not available");
@@ -209,7 +212,7 @@ private void doRequest(PrometheusRegistry registry, String method) throws IOExce
209212
try {
210213
if (!method.equals("DELETE")) {
211214
OutputStream outputStream = connection.getOutputStream();
212-
writer.write(outputStream, registry.scrape(), EscapingScheme.NO_ESCAPING);
215+
writer.write(outputStream, registry.scrape(), this.escapingScheme);
213216
outputStream.flush();
214217
outputStream.close();
215218
}
@@ -435,6 +438,20 @@ private String getJob(ExporterPushgatewayProperties properties) {
435438
}
436439
}
437440

441+
private EscapingScheme getEscapingScheme(ExporterPushgatewayProperties properties) {
442+
if (properties != null && properties.getEscapingScheme() != null) {
443+
String scheme = properties.getEscapingScheme();
444+
switch (scheme) {
445+
case "no-escaping": return EscapingScheme.NO_ESCAPING;
446+
case "values": return EscapingScheme.VALUE_ENCODING_ESCAPING;
447+
case "underscores": return EscapingScheme.UNDERSCORE_ESCAPING;
448+
case "dots": return EscapingScheme.DOTS_ESCAPING;
449+
default: return EscapingScheme.NO_ESCAPING;
450+
}
451+
}
452+
return EscapingScheme.NO_ESCAPING;
453+
}
454+
438455
private Format getFormat() {
439456
// currently not configurable via properties
440457
if (this.format != null) {
@@ -483,7 +500,8 @@ public PushGateway build() {
483500
makeUrl(properties),
484501
connectionFactory,
485502
requestHeaders,
486-
getPrometheusTimestampsInMs());
503+
getPrometheusTimestampsInMs(),
504+
getEscapingScheme(properties));
487505
} catch (MalformedURLException e) {
488506
throw new PrometheusPropertiesException(
489507
address + ": Invalid address. Expecting <host>:<port>");

prometheus-metrics-exporter-pushgateway/src/test/java/io/prometheus/metrics/exporter/pushgateway/PushGatewayTest.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@
88
import static org.mockserver.model.HttpRequest.request;
99
import static org.mockserver.model.HttpResponse.response;
1010

11+
import io.prometheus.metrics.config.PrometheusProperties;
12+
import io.prometheus.metrics.config.PrometheusPropertiesLoader;
1113
import io.prometheus.metrics.core.metrics.Gauge;
1214
import io.prometheus.metrics.model.registry.PrometheusRegistry;
15+
import io.prometheus.metrics.model.snapshots.EscapingScheme;
1316
import java.io.IOException;
1417
import java.lang.reflect.Field;
1518
import java.net.InetAddress;
1619
import java.net.URL;
20+
import java.util.Properties;
1721

1822
import io.prometheus.metrics.model.snapshots.PrometheusNaming;
1923
import io.prometheus.metrics.model.snapshots.ValidationScheme;
@@ -448,4 +452,18 @@ public void testInstanceIpEscapedGroupingKey() throws IOException {
448452
pg.delete();
449453
}
450454
}
455+
456+
@Test
457+
public void testEscapingSchemeDefaultValue() throws IllegalAccessException, NoSuchFieldException {
458+
PushGateway pg = PushGateway.builder()
459+
.address("localhost:" + mockServerClient.getPort())
460+
.job("test")
461+
.build();
462+
463+
Field escapingSchemeField = pg.getClass().getDeclaredField("escapingScheme");
464+
escapingSchemeField.setAccessible(true);
465+
EscapingScheme scheme = (EscapingScheme) escapingSchemeField.get(pg);
466+
467+
assertThat(scheme).isEqualTo(EscapingScheme.NO_ESCAPING);
468+
}
451469
}

0 commit comments

Comments
 (0)