Skip to content
Merged
Show file tree
Hide file tree
Changes from 81 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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.prometheus.metrics.expositionformats.ExpositionFormatWriter;
import io.prometheus.metrics.expositionformats.OpenMetricsTextFormatWriter;
import io.prometheus.metrics.expositionformats.PrometheusTextFormatWriter;
import io.prometheus.metrics.model.snapshots.EscapingScheme;
import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot;
import io.prometheus.metrics.model.snapshots.Labels;
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.NO_ESCAPING);
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.NO_ESCAPING);
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.NO_ESCAPING);
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.NO_ESCAPING);
return nullOutputStream;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ 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";
private final String scheme;
private final String address;
private final String job;
private final String escapingScheme;

private ExporterPushgatewayProperties(String address, String job, String scheme) {
private ExporterPushgatewayProperties(
String address, String job, String scheme, String 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 @@ -39,6 +43,14 @@ public String getScheme() {
return scheme;
}

/**
* Escaping scheme to be used when pushing metric data to the pushgateway. Valid values:
* "no-escaping", "values", "underscores", "dots". Default is "no-escaping".
*/
public String 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 @@ -48,6 +60,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 @@ -56,6 +70,20 @@ static ExporterPushgatewayProperties load(Map<Object, Object> properties)
PREFIX, SCHEME, scheme));
}
}
return new ExporterPushgatewayProperties(address, job, scheme);

if (escapingScheme != null) {
if (!escapingScheme.equals("no-escaping")
&& !escapingScheme.equals("values")
&& !escapingScheme.equals("underscores")
&& !escapingScheme.equals("dots")) {
throw new PrometheusPropertiesException(
String.format(
"%s.%s: Illegal value. Expecting 'no-escaping', 'values', 'underscores', "
+ "or 'dots'. Found: %s",
PREFIX, ESCAPING_SCHEME, escapingScheme));
}
}

return new ExporterPushgatewayProperties(address, job, scheme, escapingScheme);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Properties;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -37,15 +38,19 @@ public void testBuilder() {
PrometheusProperties defaults = PrometheusPropertiesLoader.load(new HashMap<>());
PrometheusProperties.Builder builder = PrometheusProperties.builder();
builder.defaultMetricsProperties(defaults.getDefaultMetricProperties());
builder.metricProperties(
Collections.singletonMap(
"http_duration_seconds",
MetricsProperties.builder().histogramClassicUpperBounds(0.1, 0.2, 0.5, 1.0).build()));
builder.exemplarProperties(defaults.getExemplarProperties());
builder.defaultMetricsProperties(defaults.getDefaultMetricProperties());
builder.exporterFilterProperties(defaults.getExporterFilterProperties());
builder.exporterHttpServerProperties(defaults.getExporterHttpServerProperties());
builder.exporterOpenTelemetryProperties(defaults.getExporterOpenTelemetryProperties());
builder.pushgatewayProperties(defaults.getExporterPushgatewayProperties());
builder.exporterProperties(defaults.getExporterProperties());
PrometheusProperties result = builder.build();
assertThat(result.getDefaultMetricProperties()).isSameAs(defaults.getDefaultMetricProperties());
assertThat(result.getDefaultMetricProperties()).isSameAs(defaults.getDefaultMetricProperties());
assertThat(result.getExemplarProperties()).isSameAs(defaults.getExemplarProperties());
assertThat(result.getExporterFilterProperties())
.isSameAs(defaults.getExporterFilterProperties());
Expand All @@ -55,5 +60,11 @@ public void testBuilder() {
.isSameAs(defaults.getExporterOpenTelemetryProperties());
assertThat(result.getExporterPushgatewayProperties())
.isSameAs(defaults.getExporterPushgatewayProperties());
assertThat(result.getMetricProperties("http_duration_seconds"))
.usingRecursiveComparison()
.isEqualTo(
MetricsProperties.builder().histogramClassicUpperBounds(0.1, 0.2, 0.5, 1.0).build());
assertThat(result.getMetricProperties("unknown_metric")).isNull();
assertThat(result.getExporterProperties()).isSameAs(defaults.getExporterProperties());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
import io.prometheus.metrics.model.snapshots.EscapingScheme;
import io.prometheus.metrics.model.snapshots.Exemplar;
import io.prometheus.metrics.model.snapshots.Label;
import io.prometheus.metrics.model.snapshots.Labels;
Expand All @@ -23,6 +24,8 @@
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class CounterTest {

Expand Down Expand Up @@ -104,22 +107,21 @@ public void testLabels() {
assertThat(getValue(labels, "l", "b")).isCloseTo(3.0, offset(.001));
}

@Test
public void testTotalStrippedFromName() {
for (String name :
new String[] {
"my_counter_total", "my.counter.total",
"my_counter_seconds_total", "my.counter.seconds.total",
"my_counter", "my.counter",
"my_counter_seconds", "my.counter.seconds"
}) {
Counter counter = Counter.builder().name(name).unit(Unit.SECONDS).build();
Metrics.MetricFamily protobufData =
new PrometheusProtobufWriterImpl().convert(counter.collect());
assertThat(ProtobufUtil.shortDebugString(protobufData))
.isEqualTo(
"name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }");
}
@ParameterizedTest
@ValueSource(
strings = {
"my_counter_total",
"my_counter_seconds_total",
"my_counter",
"my_counter_seconds",
})
public void testTotalStrippedFromName(String name) {
Counter counter = Counter.builder().name(name).unit(Unit.SECONDS).build();
Metrics.MetricFamily protobufData =
new PrometheusProtobufWriterImpl().convert(counter.collect(), EscapingScheme.NO_ESCAPING);
assertThat(ProtobufUtil.shortDebugString(protobufData))
.isEqualTo(
"name: \"my_counter_seconds_total\" type: COUNTER metric { counter { value: 0.0 } }");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@
import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_31_1.Metrics;
import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
import io.prometheus.metrics.model.snapshots.ClassicHistogramBucket;
import io.prometheus.metrics.model.snapshots.Exemplar;
import io.prometheus.metrics.model.snapshots.Exemplars;
import io.prometheus.metrics.model.snapshots.HistogramSnapshot;
import io.prometheus.metrics.model.snapshots.Labels;
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
import io.prometheus.metrics.model.snapshots.*;
import io.prometheus.metrics.tracer.common.SpanContext;
import io.prometheus.metrics.tracer.initializer.SpanContextSupplier;
import java.io.ByteArrayOutputStream;
Expand Down Expand Up @@ -91,7 +86,8 @@ private void run() throws NoSuchFieldException, IllegalAccessException {
}
}
Metrics.MetricFamily protobufData =
new PrometheusProtobufWriterImpl().convert(histogram.collect());
new PrometheusProtobufWriterImpl()
.convert(histogram.collect(), EscapingScheme.NO_ESCAPING);
String expectedWithMetadata =
"name: \"test\" type: HISTOGRAM metric { histogram { " + expected + " } }";
assertThat(ProtobufUtil.shortDebugString(protobufData))
Expand Down Expand Up @@ -946,13 +942,14 @@ public void testDefaults() throws IOException {
""";

// protobuf
Metrics.MetricFamily protobufData = new PrometheusProtobufWriterImpl().convert(snapshot);
Metrics.MetricFamily protobufData =
new PrometheusProtobufWriterImpl().convert(snapshot, EscapingScheme.NO_ESCAPING);
assertThat(ProtobufUtil.shortDebugString(protobufData)).isEqualTo(expectedProtobuf);

// text
ByteArrayOutputStream out = new ByteArrayOutputStream();
OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(false, true);
writer.write(out, MetricSnapshots.of(snapshot));
writer.write(out, MetricSnapshots.of(snapshot), EscapingScheme.NO_ESCAPING);
assertThat(out).hasToString(expectedTextFormat);
}

Expand Down Expand Up @@ -1259,12 +1256,6 @@ public void testIllegalLabelNamePrefix() {
.isThrownBy(() -> Histogram.builder().name("test").labelNames("__hello"));
}

@Test
public void testIllegalName() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> Histogram.builder().name("my_namespace/server.durations"));
}

@Test
public void testNoName() {
assertThatExceptionOfType(IllegalArgumentException.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,30 @@
import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_31_1.Metrics;
import io.prometheus.metrics.expositionformats.internal.PrometheusProtobufWriterImpl;
import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
import io.prometheus.metrics.model.snapshots.EscapingScheme;
import io.prometheus.metrics.model.snapshots.Labels;
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
import io.prometheus.metrics.model.snapshots.Unit;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

class InfoTest {

@Test
public void testInfoStrippedFromName() {
for (String name :
new String[] {
"jvm.runtime", "jvm_runtime",
"jvm.runtime.info", "jvm_runtime_info"
}) {
for (String labelName : new String[] {"my.key", "my_key"}) {
Info info = Info.builder().name(name).labelNames(labelName).build();
info.addLabelValues("value");
Metrics.MetricFamily protobufData =
new PrometheusProtobufWriterImpl().convert(info.collect());
assertThat(ProtobufUtil.shortDebugString(protobufData))
.isEqualTo(
"name: \"jvm_runtime_info\" type: GAUGE metric { label { name: \"my_key\" value:"
+ " \"value\" } gauge { value: 1.0 } }");
}
}
@ParameterizedTest
@ValueSource(strings = {"jvm.runtime", "jvm.runtime.info"})
public void testInfoStrippedFromName(String name) {
Info info = Info.builder().name(name).labelNames("my.key").build();
info.addLabelValues("value");
Metrics.MetricFamily protobufData =
new PrometheusProtobufWriterImpl().convert(info.collect(), EscapingScheme.NO_ESCAPING);
assertThat(ProtobufUtil.shortDebugString(protobufData))
.isEqualTo(
"name: \"jvm.runtime_info\" type: GAUGE metric { label { name: \"my.key\" value:"
+ " \"value\" } gauge { value: 1.0 } }");
}

@Test
Expand Down Expand Up @@ -126,7 +122,8 @@ public void testConstLabelsDuplicate2() {
private void assertTextFormat(String expected, Info info) throws IOException {
OpenMetricsTextFormatWriter writer = new OpenMetricsTextFormatWriter(true, true);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
writer.write(outputStream, MetricSnapshots.of(info.collect()));
writer.write(
outputStream, MetricSnapshots.of(info.collect()), EscapingScheme.UNDERSCORE_ESCAPING);
String result = outputStream.toString(StandardCharsets.UTF_8.name());
if (!result.contains(expected)) {
throw new AssertionError(expected + " is not contained in the following output:\n" + result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import io.prometheus.metrics.expositionformats.ExpositionFormats;
import io.prometheus.metrics.model.registry.MetricNameFilter;
import io.prometheus.metrics.model.registry.PrometheusRegistry;
import io.prometheus.metrics.model.snapshots.EscapingScheme;
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand Down Expand Up @@ -54,10 +55,11 @@ public void handleRequest(PrometheusHttpExchange exchange) throws IOException {
try {
PrometheusHttpRequest request = exchange.getRequest();
MetricSnapshots snapshots = scrape(request);
if (writeDebugResponse(snapshots, exchange)) {
String acceptHeader = request.getHeader("Accept");
EscapingScheme escapingScheme = EscapingScheme.fromAcceptHeader(acceptHeader);
if (writeDebugResponse(snapshots, escapingScheme, exchange)) {
return;
}
String acceptHeader = request.getHeader("Accept");
ExpositionFormatWriter writer = expositionFormats.findWriter(acceptHeader);
PrometheusHttpResponse response = exchange.getResponse();
response.setHeader("Content-Type", writer.getContentType());
Expand All @@ -66,12 +68,12 @@ public void handleRequest(PrometheusHttpExchange exchange) throws IOException {
response.setHeader("Content-Encoding", "gzip");
try (GZIPOutputStream gzipOutputStream =
new GZIPOutputStream(response.sendHeadersAndGetBody(200, 0))) {
writer.write(gzipOutputStream, snapshots);
writer.write(gzipOutputStream, snapshots, escapingScheme);
}
} else {
ByteArrayOutputStream responseBuffer =
new ByteArrayOutputStream(lastResponseSize.get() + 1024);
writer.write(responseBuffer, snapshots);
writer.write(responseBuffer, snapshots, escapingScheme);
lastResponseSize.set(responseBuffer.size());
int contentLength = responseBuffer.size();
if (contentLength > 0) {
Expand Down Expand Up @@ -136,7 +138,8 @@ private MetricSnapshots scrape(PrometheusHttpRequest request) {
}
}

private boolean writeDebugResponse(MetricSnapshots snapshots, PrometheusHttpExchange exchange)
private boolean writeDebugResponse(
MetricSnapshots snapshots, EscapingScheme escapingScheme, PrometheusHttpExchange exchange)
throws IOException {
String debugParam = exchange.getRequest().getParameter("debug");
PrometheusHttpResponse response = exchange.getResponse();
Expand All @@ -148,14 +151,16 @@ private boolean writeDebugResponse(MetricSnapshots snapshots, PrometheusHttpExch
OutputStream body = response.sendHeadersAndGetBody(responseStatus, 0);
switch (debugParam) {
case "openmetrics":
expositionFormats.getOpenMetricsTextFormatWriter().write(body, snapshots);
expositionFormats.getOpenMetricsTextFormatWriter().write(body, snapshots, escapingScheme);
break;
case "text":
expositionFormats.getPrometheusTextFormatWriter().write(body, snapshots);
expositionFormats.getPrometheusTextFormatWriter().write(body, snapshots, escapingScheme);
break;
case "prometheus-protobuf":
String debugString =
expositionFormats.getPrometheusProtobufWriter().toDebugString(snapshots);
expositionFormats
.getPrometheusProtobufWriter()
.toDebugString(snapshots, escapingScheme);
body.write(debugString.getBytes(StandardCharsets.UTF_8));
break;
default:
Expand Down
Loading