Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
5445c1d
Add UTF-8 support in metric and label names
fedetorres93 Jan 3, 2025
7939aba
Add grouping key escaping for URLs in Pushgateway exporter
fedetorres93 Jan 7, 2025
b5260be
Merge branch 'main' into ftorres/utf-8
fedetorres93 Jan 9, 2025
8444ae9
Merge branch 'main' into ftorres/utf-8
fedetorres93 Jan 20, 2025
a593d4e
Fix escaping bugs
fedetorres93 Jan 21, 2025
5f9726f
Merge branch 'main' into ftorres/utf-8
fedetorres93 Jul 8, 2025
f9ce942
Fix tests
fedetorres93 Jul 10, 2025
a64dda8
Make statics in PrometheusNaming final
fedetorres93 Jul 15, 2025
afc3156
Fix write errors in tests
fedetorres93 Jul 19, 2025
314838d
Add getter for nameValidationScheme
fedetorres93 Jul 25, 2025
ce9aeb2
Change NameType accessibility
fedetorres93 Aug 6, 2025
65bfb6b
Remove prefix argument from load method in NamingProperties
fedetorres93 Aug 6, 2025
e918ca3
Remove redundant null check in initValidationScheme
fedetorres93 Aug 6, 2025
e2aacd5
Refactor escaped snapshots creation
fedetorres93 Aug 6, 2025
7204288
Extract common logic in escaping tests
fedetorres93 Aug 7, 2025
891d28d
Parameterize testFindWriter
fedetorres93 Aug 7, 2025
8143f69
Add escaping scheme to ExporterPushgatewayProperties
fedetorres93 Aug 7, 2025
2f5bd9c
Formatting
fedetorres93 Aug 7, 2025
861b8a2
Update comment
fedetorres93 Aug 7, 2025
b98e054
Remove variable reassignment in escaping tests
fedetorres93 Aug 7, 2025
263d805
use string builder for performance
zeitlinger Aug 8, 2025
27362ee
naming
zeitlinger Aug 8, 2025
16a8fd8
Merge remote-tracking branch 'origin/main' into ftorres/utf-8
zeitlinger Aug 8, 2025
c5de174
fix merge
zeitlinger Aug 8, 2025
3418c7e
format
zeitlinger Aug 8, 2025
717dbfb
use parameterized tests
zeitlinger Aug 8, 2025
1a60037
use parameterized tests
zeitlinger Aug 8, 2025
a1b3226
use parameterized tests
zeitlinger Aug 8, 2025
2d11b31
use parameterized tests
zeitlinger Aug 8, 2025
5734772
avoid mocks
zeitlinger Aug 8, 2025
5eb637a
avoid mocks
zeitlinger Aug 8, 2025
ed474d6
format
zeitlinger Aug 8, 2025
81802aa
format
zeitlinger Aug 8, 2025
075ce06
format
zeitlinger Aug 8, 2025
2949497
format
zeitlinger Aug 8, 2025
5017849
format
zeitlinger Aug 8, 2025
15e98bb
format
zeitlinger Aug 8, 2025
3b61ad1
format
zeitlinger Aug 8, 2025
00835eb
format
zeitlinger Aug 8, 2025
be6bd43
cleanup
zeitlinger Aug 8, 2025
6498aca
be strict about validation scheme validation
zeitlinger Aug 8, 2025
c5b70bc
coverage
zeitlinger Aug 8, 2025
bc859f3
reject empty labels
zeitlinger Aug 8, 2025
4e406d0
coverage
zeitlinger Aug 8, 2025
01d21c6
fix test
zeitlinger Aug 8, 2025
109e077
coverage
zeitlinger Aug 8, 2025
cddd829
ensure binary compatibility
zeitlinger Aug 8, 2025
f37fe6b
javadoc
zeitlinger Aug 8, 2025
cca01f6
coverage
zeitlinger Aug 8, 2025
cc6571f
prom name can't be null
zeitlinger Aug 11, 2025
551d6c6
fix prometheus name check
zeitlinger Aug 11, 2025
bd7b29e
use underscore escaping for backwards compatability
zeitlinger Aug 11, 2025
88f9b8b
fix prometheus name check
zeitlinger Aug 11, 2025
be07075
fix prometheus name check
zeitlinger Aug 11, 2025
d47af4e
fix escaping
zeitlinger Aug 11, 2025
fba0594
fix escaping
zeitlinger Aug 11, 2025
6c11f86
fix escaping
zeitlinger Aug 11, 2025
f39d9be
fix escaping
zeitlinger Aug 11, 2025
8bfcdfe
remove validation scheme
zeitlinger Aug 12, 2025
a928ea7
remove validation scheme
zeitlinger Aug 12, 2025
842b993
__name__ can't be used in labels
zeitlinger Aug 12, 2025
e61f127
escape exemplars
zeitlinger Aug 12, 2025
203361e
format
zeitlinger Aug 12, 2025
7f2c52a
fix tests
zeitlinger Aug 12, 2025
bdb73bc
fix tests
zeitlinger Aug 12, 2025
28b2fa0
extract snapshot escaper
zeitlinger Aug 12, 2025
ccef1a8
extract snapshot escaper
zeitlinger Aug 12, 2025
001ab86
extract snapshot escaper
zeitlinger Aug 12, 2025
eee53be
extract snapshot escaper
zeitlinger Aug 12, 2025
c8c1e9b
avoid redundant escaping
zeitlinger Aug 12, 2025
a57b4e6
coverage
zeitlinger Aug 13, 2025
d4d4516
unescape is not used
zeitlinger Aug 13, 2025
a210cb8
prepare move snapshot escaper
zeitlinger Aug 13, 2025
7244c59
move snapshot escaper
zeitlinger Aug 13, 2025
fbd94e6
coverage
zeitlinger Aug 13, 2025
6f1b6a3
fix
zeitlinger Aug 13, 2025
47554b2
fix
zeitlinger Aug 13, 2025
1f52452
don't validate in escape
zeitlinger Aug 13, 2025
858462d
don't validate in escape
zeitlinger Aug 13, 2025
f71905e
fix
zeitlinger Aug 13, 2025
f18e6c4
fix
zeitlinger Aug 13, 2025
789e57b
add docs
zeitlinger Aug 13, 2025
97cb296
add docs
zeitlinger Aug 13, 2025
ca30161
move EscapingScheme
zeitlinger Aug 13, 2025
71abbe9
Merge branch 'main' into ftorres/utf-8
zeitlinger Aug 13, 2025
c02ac18
move EscapingScheme
zeitlinger Aug 13, 2025
07c54b8
nullaway
zeitlinger Aug 14, 2025
0f378df
properties should never be null
zeitlinger Aug 14, 2025
d260bf3
properties should never be null
zeitlinger Aug 14, 2025
0506165
nullaway
zeitlinger Aug 14, 2025
1b2d2e5
is sampler enabled
zeitlinger Aug 14, 2025
c041128
nullaway
zeitlinger Aug 14, 2025
8b703d0
nullaway
zeitlinger Aug 14, 2025
1c0e85a
nullaway
zeitlinger Aug 14, 2025
fb842ab
nullaway
zeitlinger Aug 14, 2025
80817b6
nullaway
zeitlinger Aug 14, 2025
db0fc2b
nullaway
zeitlinger Aug 14, 2025
697effc
nullaway
zeitlinger Aug 14, 2025
99fd8f3
nullaway
zeitlinger Aug 14, 2025
d9e1e77
nullaway
zeitlinger Aug 14, 2025
3662341
nullaway
zeitlinger Aug 14, 2025
29c2ba2
nullaway
zeitlinger Aug 14, 2025
fd0900c
nullaway
zeitlinger Aug 14, 2025
5ad2090
nullaway
zeitlinger Aug 14, 2025
fdd2f5c
Merge branch 'nullaway' into ftorres/utf-8
zeitlinger Aug 14, 2025
330eb16
format
zeitlinger Aug 14, 2025
84c5118
exclude tests and examples
zeitlinger Aug 14, 2025
ffc8609
docs
zeitlinger Aug 14, 2025
ae009cf
rename escaping scheme value for no escaping
zeitlinger Aug 14, 2025
3075318
Merge remote-tracking branch 'origin/nullaway' into ftorres/utf-8
zeitlinger Aug 14, 2025
74d1a24
Merge remote-tracking branch 'origin/main' into ftorres/utf-8
zeitlinger Aug 14, 2025
530d512
format
zeitlinger Aug 14, 2025
fae2c60
Merge remote-tracking branch 'origin/main' into ftorres/utf-8
zeitlinger Aug 15, 2025
2c53f49
fix
zeitlinger Aug 15, 2025
8f04695
remove unused file
zeitlinger Aug 18, 2025
f9d6e03
Merge branch 'main' into ftorres/utf-8
zeitlinger Aug 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .github/super-linter.env
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ VALIDATE_GO_MODULES=false
VALIDATE_HTML=false
# done by checkstyle
VALIDATE_JAVA=false
# contradicting with prettier
VALIDATE_JAVASCRIPT_STANDARD=false
# we have many duplicate code in our codebase for demo purposes
VALIDATE_JSCPD=false
VALIDATE_PYTHON_PYLINT=false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.prometheus.metrics.benchmarks;

import io.prometheus.metrics.config.EscapingScheme;
import io.prometheus.metrics.expositionformats.ExpositionFormatWriter;
import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
import io.prometheus.metrics.expositionformats.PrometheusTextFormatWriter;
Expand Down Expand Up @@ -69,14 +70,15 @@ public OutputStream openMetricsWriteToByteArray(WriterState writerState) throws
// avoid growing the array
ByteArrayOutputStream byteArrayOutputStream = writerState.byteArrayOutputStream;
byteArrayOutputStream.reset();
OPEN_METRICS_TEXT_FORMAT_WRITER.write(byteArrayOutputStream, SNAPSHOTS);
OPEN_METRICS_TEXT_FORMAT_WRITER.write(
byteArrayOutputStream, SNAPSHOTS, EscapingScheme.ALLOW_UTF8);
return byteArrayOutputStream;
}

@Benchmark
public OutputStream openMetricsWriteToNull() throws IOException {
OutputStream nullOutputStream = NullOutputStream.INSTANCE;
OPEN_METRICS_TEXT_FORMAT_WRITER.write(nullOutputStream, SNAPSHOTS);
OPEN_METRICS_TEXT_FORMAT_WRITER.write(nullOutputStream, SNAPSHOTS, EscapingScheme.ALLOW_UTF8);
return nullOutputStream;
}

Expand All @@ -85,14 +87,15 @@ public OutputStream prometheusWriteToByteArray(WriterState writerState) throws I
// avoid growing the array
ByteArrayOutputStream byteArrayOutputStream = writerState.byteArrayOutputStream;
byteArrayOutputStream.reset();
PROMETHEUS_TEXT_FORMAT_WRITER.write(byteArrayOutputStream, SNAPSHOTS);
PROMETHEUS_TEXT_FORMAT_WRITER.write(
byteArrayOutputStream, SNAPSHOTS, EscapingScheme.ALLOW_UTF8);
return byteArrayOutputStream;
}

@Benchmark
public OutputStream prometheusWriteToNull() throws IOException {
OutputStream nullOutputStream = NullOutputStream.INSTANCE;
PROMETHEUS_TEXT_FORMAT_WRITER.write(nullOutputStream, SNAPSHOTS);
PROMETHEUS_TEXT_FORMAT_WRITER.write(nullOutputStream, SNAPSHOTS, EscapingScheme.ALLOW_UTF8);
return nullOutputStream;
}

Expand Down
21 changes: 13 additions & 8 deletions docs/content/config/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Future releases will add more options, like configuration via environment variab
Example:

```properties
io.prometheus.exporter.httpServer.port = 9401
io.prometheus.exporter.httpServer.port=9401
```

The property above changes the port for the
Expand Down Expand Up @@ -71,13 +71,13 @@ metric only by specifying the metric name. Example:
Let's say you have a histogram named `latency_seconds`.

```properties
io.prometheus.metrics.histogramClassicUpperBounds = 0.2, 0.4, 0.8, 1.0
io.prometheus.metrics.histogramClassicUpperBounds=0.2, 0.4, 0.8, 1.0
```

The line above sets histogram buckets for all histograms. However:

```properties
io.prometheus.metrics.latency_seconds.histogramClassicUpperBounds = 0.2, 0.4, 0.8, 1.0
io.prometheus.metrics.latency_seconds.histogramClassicUpperBounds=0.2, 0.4, 0.8, 1.0
```

The line above sets histogram buckets only for the histogram named `latency_seconds`.
Expand Down Expand Up @@ -170,10 +170,15 @@ See Javadoc for details.

<!-- editorconfig-checker-disable -->

| Name | Javadoc | Note |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| io.prometheus.exporter.pushgateway.address | [PushGateway.Builder.address()](</client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#address(java.lang.String)>) | |
| io.prometheus.exporter.pushgateway.scheme | [PushGateway.Builder.scheme()](</client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#scheme(java.lang.String)>) | |
| io.prometheus.exporter.pushgateway.job | [PushGateway.Builder.job()](</client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#job(java.lang.String)>) | |
| Name | Javadoc | Note |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---- |
| io.prometheus.exporter.pushgateway.address | [PushGateway.Builder.address()](</client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#address(java.lang.String)>) | |
| io.prometheus.exporter.pushgateway.scheme | [PushGateway.Builder.scheme()](</client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#scheme(java.lang.String)>) | |
| io.prometheus.exporter.pushgateway.job | [PushGateway.Builder.job()](</client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#job(java.lang.String)>) | |
| io.prometheus.exporter.pushgateway.escapingScheme | [PushGateway.Builder.escapingScheme()](</client_java/api/io/prometheus/metrics/exporter/pushgateway/PushGateway.Builder.html#escapingScheme(io.prometheus.metrics.config.EscapingScheme)>) | (1) |

<!-- editorconfig-checker-enable -->

(1) Escaping scheme can be `allow-utf-8`, `underscores`, `dots`, or `values` as described in
[escaping schemes](https://github.com/prometheus/docs/blob/main/docs/instrumenting/escaping_schemes.md#escaping-schemes) <!-- editorconfig-checker-disable-line -->
and in the [Unicode documentation]({{< relref "../exporters/unicode.md" >}}).
2 changes: 1 addition & 1 deletion docs/content/exporters/filter.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Filter
weight: 2
weight: 3
---

All exporters support a `name[]` URL parameter for querying only specific metric names. Examples:
Expand Down
2 changes: 1 addition & 1 deletion docs/content/exporters/httpserver.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: HTTPServer
weight: 3
weight: 4
---

The `HTTPServer` is a standalone server for exposing a metric endpoint. A minimal example
Expand Down
2 changes: 1 addition & 1 deletion docs/content/exporters/pushgateway.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Pushgateway
weight: 5
weight: 6
---

The [Prometheus Pushgateway](https://github.com/prometheus/pushgateway) exists to allow ephemeral
Expand Down
2 changes: 1 addition & 1 deletion docs/content/exporters/servlet.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Servlet
weight: 4
weight: 5
---

The
Expand Down
2 changes: 1 addition & 1 deletion docs/content/exporters/spring.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Spring
weight: 5
weight: 7
---

## Alternative: Use Spring's Built-in Metrics Library
Expand Down
29 changes: 29 additions & 0 deletions docs/content/exporters/unicode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Unicode
weight: 2
---

The Prometheus Java client library allows all Unicode characters, that can be encoded as UTF-8.

At scrape time, some characters are replaced based on the `encoding` header according
to
the [Escaping scheme](https://github.com/prometheus/docs/blob/main/docs/instrumenting/escaping_schemes.md). <!-- editorconfig-checker-disable-line -->

For example, if you use the `underscores` escaping scheme, dots in metric and label names are
replaced with underscores, so that the metric name `http.server.duration` becomes
`http_server_duration`.

Prometheus servers that do not support Unicode at all will not pass the `encoding` header, and the
Prometheus Java client library will replace dots, as well as any character that is not in the legacy
character set (`a-zA-Z0-9_:`), with underscores by default.

When `escaping=allow-utf-8` is passed, add valid UTF-8 characters to the metric and label names
without replacing them. This allows you to use dots in metric and label names, as well as
other UTF-8 characters, without any replacements.

## PushGateway

When using the [Pushgateway](/exporters/pushgateway/), Unicode support has to be enabled
explicitly by setting `io.prometheus.exporter.pushgateway.escapingScheme` to `allow-utf-8` in the
Pushgateway configuration file - see
[Pushgateway configuration]({{< relref "/config/config.md#exporter-pushgateway-properties" >}})
16 changes: 5 additions & 11 deletions docs/content/otel/names.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ the Prometheus server as if you had exposed Prometheus metrics directly.

The main steps when converting OpenTelemetry metric names to Prometheus metric names are:

- Replace dots with underscores.
- Escape illegal characters as described in [Unicode support]
- If the metric has a unit, append the unit to the metric name, like `_seconds`.
- If the metric type has a suffix, append it, like `_total` for counters.

Expand All @@ -29,14 +29,8 @@ OpenTelemetry's [Semantic Conventions for HTTP Metrics](https://opentelemetry.io
say that if you instrument an HTTP server with OpenTelemetry, you must have a histogram named
`http.server.duration`.

Most names defined in semantic conventions use dots. In the Prometheus server, the dot is an illegal
character (this might change in future versions of the Prometheus server).
Most names defined in semantic conventions use dots.
Dots in metric and label names are now supported in the Prometheus Java client library as
described in [Unicode support].

The Prometheus Java client library allows dots, so that you can use metric names and label names as
defined in OpenTelemetry's semantic conventions.
The dots will automatically be replaced with underscores if you expose metrics in Prometheus format,
but you will see the original names with dots if you push your metrics in OpenTelemetry format.

That way, you can use OTel-compliant metric and label names today when instrumenting your
application with the Prometheus Java client, and you are prepared in case your monitoring backend
adds features in the future that require OTel-compliant instrumentation.
[Unicode support]: {{< relref "../exporters/unicode.md" >}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package io.prometheus.metrics.config;

import javax.annotation.Nullable;

public enum EscapingScheme {
/** NO_ESCAPING indicates that a name will not be escaped. */
ALLOW_UTF8("allow-utf-8"),

/** UNDERSCORE_ESCAPING replaces all legacy-invalid characters with underscores. */
UNDERSCORE_ESCAPING("underscores"),

/**
* DOTS_ESCAPING is similar to UNDERSCORE_ESCAPING, except that dots are converted to `_dot_` and
* pre-existing underscores are converted to `__`.
*/
DOTS_ESCAPING("dots"),

/**
* VALUE_ENCODING_ESCAPING prepends the name with `U__` and replaces all invalid characters with
* the Unicode value, surrounded by underscores. Single underscores are replaced with double
* underscores.
*/
VALUE_ENCODING_ESCAPING("values");

private static final String ESCAPING_KEY = "escaping";

/** Default escaping scheme for names when not specified. */
public static final EscapingScheme DEFAULT = UNDERSCORE_ESCAPING;

public final String getValue() {
return value;
}

private final String value;

EscapingScheme(String value) {
this.value = value;
}

/**
* fromAcceptHeader returns an EscapingScheme depending on the Accept header. Iff the header
* contains an escaping=allow-utf-8 term, it will select NO_ESCAPING. If a valid "escaping" term
* exists, that will be used. Otherwise, the global default will be returned.
*/
public static EscapingScheme fromAcceptHeader(@Nullable String acceptHeader) {
if (acceptHeader != null) {
for (String p : acceptHeader.split(";")) {
String[] toks = p.split("=");
if (toks.length != 2) {
continue;
}
String key = toks[0].trim();
String value = toks[1].trim();
if (key.equals(ESCAPING_KEY)) {
try {
return EscapingScheme.forString(value);
} catch (IllegalArgumentException e) {
// If the escaping parameter is unknown, ignore it.
return DEFAULT;
}
}
}
}
return DEFAULT;
}

static EscapingScheme forString(String value) {
switch (value) {
case "allow-utf-8":
return ALLOW_UTF8;
case "underscores":
return UNDERSCORE_ESCAPING;
case "dots":
return DOTS_ESCAPING;
case "values":
return VALUE_ENCODING_ESCAPING;
default:
throw new IllegalArgumentException("Unknown escaping scheme: " + value);
}
}

public String toHeaderFormat() {
return "; " + ESCAPING_KEY + "=" + value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@ public class ExporterPushgatewayProperties {
private static final String ADDRESS = "address";
private static final String JOB = "job";
private static final String SCHEME = "scheme";
private static final String ESCAPING_SCHEME = "escapingScheme";
private static final String PREFIX = "io.prometheus.exporter.pushgateway";
@Nullable private final String scheme;
@Nullable private final String address;
@Nullable private final String job;
@Nullable private final EscapingScheme escapingScheme;

private ExporterPushgatewayProperties(
@Nullable String address, @Nullable String job, @Nullable String scheme) {
@Nullable String address,
@Nullable String job,
@Nullable String scheme,
@Nullable EscapingScheme escapingScheme) {
this.address = address;
this.job = job;
this.scheme = scheme;
this.escapingScheme = escapingScheme;
}

/** Address of the Pushgateway in the form {@code host:port}. Default is {@code localhost:9091} */
Expand All @@ -44,6 +50,12 @@ public String getScheme() {
return scheme;
}

/** Escaping scheme to be used when pushing metric data to the pushgateway. */
@Nullable
public EscapingScheme getEscapingScheme() {
return escapingScheme;
}

/**
* Note that this will remove entries from {@code properties}. This is because we want to know if
* there are unused properties remaining after all properties have been loaded.
Expand All @@ -53,6 +65,8 @@ static ExporterPushgatewayProperties load(Map<Object, Object> properties)
String address = Util.loadString(PREFIX + "." + ADDRESS, properties);
String job = Util.loadString(PREFIX + "." + JOB, properties);
String scheme = Util.loadString(PREFIX + "." + SCHEME, properties);
String escapingScheme = Util.loadString(PREFIX + "." + ESCAPING_SCHEME, properties);

if (scheme != null) {
if (!scheme.equals("http") && !scheme.equals("https")) {
throw new PrometheusPropertiesException(
Expand All @@ -61,7 +75,31 @@ static ExporterPushgatewayProperties load(Map<Object, Object> properties)
PREFIX, SCHEME, scheme));
}
}
return new ExporterPushgatewayProperties(address, job, scheme);

return new ExporterPushgatewayProperties(
address, job, scheme, parseEscapingScheme(escapingScheme));
}

private static @Nullable EscapingScheme parseEscapingScheme(@Nullable String scheme) {
if (scheme == null) {
return null;
}
switch (scheme) {
case "allow-utf-8":
return EscapingScheme.ALLOW_UTF8;
case "values":
return EscapingScheme.VALUE_ENCODING_ESCAPING;
case "underscores":
return EscapingScheme.UNDERSCORE_ESCAPING;
case "dots":
return EscapingScheme.DOTS_ESCAPING;
default:
throw new PrometheusPropertiesException(
String.format(
"%s.%s: Illegal value. Expecting 'allow-utf-8', 'values', 'underscores', "
+ "or 'dots'. Found: %s",
PREFIX, ESCAPING_SCHEME, scheme));
}
}

public static Builder builder() {
Expand All @@ -72,6 +110,7 @@ public static class Builder {
@Nullable private String address;
@Nullable private String job;
@Nullable private String scheme;
@Nullable private EscapingScheme escapingScheme;

private Builder() {}

Expand All @@ -90,8 +129,13 @@ public Builder scheme(String scheme) {
return this;
}

public Builder escapingScheme(EscapingScheme escapingScheme) {
this.escapingScheme = escapingScheme;
return this;
}

public ExporterPushgatewayProperties build() {
return new ExporterPushgatewayProperties(address, job, scheme);
return new ExporterPushgatewayProperties(address, job, scheme, escapingScheme);
}
}
}
Loading