Skip to content

Commit 5f587b8

Browse files
committed
Fix legacy and UTF-8 validations
Signed-off-by: Federico Torres <[email protected]>
1 parent 6561322 commit 5f587b8

File tree

6 files changed

+109
-36
lines changed

6 files changed

+109
-36
lines changed

prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/OpenMetricsTextFormatWriter.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,7 @@ private void writeNameAndLabels(OutputStreamWriter writer, String name, String s
278278

279279
if (!labels.isEmpty() || additionalLabelName != null) {
280280
writeLabels(writer, labels, additionalLabelName, additionalLabelValue, metricInsideBraces);
281-
}
282-
283-
if (metricInsideBraces) {
281+
} else if (metricInsideBraces) {
284282
writer.write('}');
285283
}
286284

prometheus-metrics-exposition-formats/src/main/java/io/prometheus/metrics/expositionformats/PrometheusTextFormatWriter.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,7 @@ private void writeNameAndLabels(OutputStreamWriter writer, String name, String s
282282

283283
if (!labels.isEmpty() || additionalLabelName != null) {
284284
writeLabels(writer, labels, additionalLabelName, additionalLabelValue, metricInsideBraces);
285-
}
286-
287-
if (metricInsideBraces) {
285+
} else if (metricInsideBraces) {
288286
writer.write('}');
289287
}
290288

prometheus-metrics-exposition-formats/src/test/java/io/prometheus/metrics/expositionformats/ExpositionFormatsTest.java

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
11
package io.prometheus.metrics.expositionformats;
22

3+
import io.prometheus.metrics.model.snapshots.*;
34
import io.prometheus.metrics.shaded.com_google_protobuf_3_21_7.TextFormat;
45
import io.prometheus.metrics.expositionformats.generated.com_google_protobuf_3_21_7.Metrics;
5-
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
66
import io.prometheus.metrics.model.snapshots.CounterSnapshot.CounterDataPointSnapshot;
7-
import io.prometheus.metrics.model.snapshots.Exemplar;
8-
import io.prometheus.metrics.model.snapshots.Exemplars;
9-
import io.prometheus.metrics.model.snapshots.ClassicHistogramBuckets;
10-
import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
117
import io.prometheus.metrics.model.snapshots.GaugeSnapshot.GaugeDataPointSnapshot;
12-
import io.prometheus.metrics.model.snapshots.HistogramSnapshot;
13-
import io.prometheus.metrics.model.snapshots.InfoSnapshot;
14-
import io.prometheus.metrics.model.snapshots.Labels;
15-
import io.prometheus.metrics.model.snapshots.MetricSnapshot;
16-
import io.prometheus.metrics.model.snapshots.MetricSnapshots;
17-
import io.prometheus.metrics.model.snapshots.NativeHistogramBuckets;
18-
import io.prometheus.metrics.model.snapshots.Quantiles;
19-
import io.prometheus.metrics.model.snapshots.StateSetSnapshot;
20-
import io.prometheus.metrics.model.snapshots.SummarySnapshot;
218
import io.prometheus.metrics.model.snapshots.SummarySnapshot.SummaryDataPointSnapshot;
22-
import io.prometheus.metrics.model.snapshots.Unit;
23-
import io.prometheus.metrics.model.snapshots.UnknownSnapshot;
249
import io.prometheus.metrics.model.snapshots.UnknownSnapshot.UnknownDataPointSnapshot;
2510
import org.junit.Assert;
2611
import org.junit.Test;
@@ -140,6 +125,7 @@ public void testCounterComplete() throws IOException {
140125
"timestamp_ms: 1672850585820 " +
141126
"}";
142127
//@formatter:on
128+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
143129

144130
CounterSnapshot counter = CounterSnapshot.builder()
145131
.name("service_time_seconds")
@@ -184,6 +170,7 @@ public void testCounterMinimal() throws IOException {
184170
"my_counter_total 1.1\n";
185171
String prometheusProtobuf = "" +
186172
"name: \"my_counter_total\" type: COUNTER metric { counter { value: 1.1 } }";
173+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
187174
CounterSnapshot counter = CounterSnapshot.builder()
188175
.name("my_counter")
189176
.dataPoint(CounterDataPointSnapshot.builder().value(1.1).build())
@@ -215,6 +202,7 @@ public void testCounterWithDots() throws IOException {
215202
"} " +
216203
"}";
217204
//@formatter:on
205+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
218206

219207
CounterSnapshot counter = CounterSnapshot.builder()
220208
.name("my.request.count")
@@ -260,6 +248,7 @@ public void testGaugeComplete() throws IOException {
260248
"timestamp_ms: 1672850585820 " +
261249
"}";
262250
//@formatter:on
251+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
263252
GaugeSnapshot gauge = GaugeSnapshot.builder()
264253
.name("disk_usage_ratio")
265254
.help("percentage used")
@@ -299,6 +288,7 @@ public void testGaugeMinimal() throws IOException {
299288
"temperature_centigrade 22.3\n";
300289
String prometheusProtobuf = "" +
301290
"name: \"temperature_centigrade\" type: GAUGE metric { gauge { value: 22.3 } }";
291+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
302292
GaugeSnapshot gauge = GaugeSnapshot.builder()
303293
.name("temperature_centigrade")
304294
.dataPoint(GaugeDataPointSnapshot.builder()
@@ -336,6 +326,7 @@ public void testGaugeWithDots() throws IOException {
336326
"} " +
337327
"}";
338328
//@formatter:on
329+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
339330

340331
GaugeSnapshot gauge = GaugeSnapshot.builder()
341332
.name("my.temperature.celsius")
@@ -354,6 +345,36 @@ public void testGaugeWithDots() throws IOException {
354345
assertPrometheusProtobuf(prometheusProtobuf, gauge);
355346
}
356347

348+
@Test
349+
public void testGaugeUTF8() throws IOException {
350+
String prometheusText =
351+
"# HELP \"gauge.name\" gauge\\ndoc\\nstr\"ing\n" +
352+
"# TYPE \"gauge.name\" gauge\n" +
353+
"{\"gauge.name\",\"name*2\"=\"val with \\\\backslash and \\\"quotes\\\"\",\"name.1\"=\"val with\\nnew line\"} +Inf\n" +
354+
"{\"gauge.name\",\"name*2\"=\"佖佥\",\"name.1\"=\"Björn\"} 3.14E42\n";
355+
PrometheusNaming.nameValidationScheme = ValidationScheme.UTF8Validation;
356+
357+
GaugeSnapshot gauge = GaugeSnapshot.builder()
358+
.name("gauge.name")
359+
.help("gauge\ndoc\nstr\"ing")
360+
.dataPoint(GaugeDataPointSnapshot.builder()
361+
.value(Double.POSITIVE_INFINITY)
362+
.labels(Labels.builder()
363+
.label("name.1", "val with\nnew line")
364+
.label("name*2", "val with \\backslash and \"quotes\"")
365+
.build())
366+
.build())
367+
.dataPoint(GaugeDataPointSnapshot.builder()
368+
.value(3.14e42)
369+
.labels(Labels.builder()
370+
.label("name.1", "Björn")
371+
.label("name*2", "佖佥")
372+
.build())
373+
.build())
374+
.build();
375+
assertPrometheusText(prometheusText, gauge);
376+
}
377+
357378
@Test
358379
public void testSummaryComplete() throws IOException {
359380
String openMetricsText = "" +
@@ -445,6 +466,7 @@ public void testSummaryComplete() throws IOException {
445466
"timestamp_ms: 1672850585820 " +
446467
"}";
447468
//@formatter:on
469+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
448470
SummarySnapshot summary = SummarySnapshot.builder()
449471
.name("http_request_duration_seconds")
450472
.help("request duration")
@@ -513,6 +535,7 @@ public void testSummaryWithoutQuantiles() throws IOException {
513535
"} " +
514536
"}";
515537
//@formatter:on
538+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
516539
SummarySnapshot summary = SummarySnapshot.builder()
517540
.name("latency_seconds")
518541
.help("latency")
@@ -548,6 +571,7 @@ public void testSummaryNoCountAndSum() throws IOException {
548571
"} " +
549572
"}";
550573
//@formatter:on
574+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
551575
SummarySnapshot summary = SummarySnapshot.builder()
552576
.name("latency_seconds")
553577
.dataPoint(SummaryDataPointSnapshot.builder()
@@ -580,6 +604,7 @@ public void testSummaryJustCount() throws IOException {
580604
"} " +
581605
"}";
582606
//@formatter:on
607+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
583608
SummarySnapshot summary = SummarySnapshot.builder()
584609
.name("latency_seconds")
585610
.dataPoint(SummaryDataPointSnapshot.builder()
@@ -612,6 +637,7 @@ public void testSummaryJustSum() throws IOException {
612637
"} " +
613638
"}";
614639
//@formatter:on
640+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
615641
SummarySnapshot summary = SummarySnapshot.builder()
616642
.name("latency_seconds")
617643
.dataPoint(SummaryDataPointSnapshot.builder()
@@ -627,6 +653,7 @@ public void testSummaryJustSum() throws IOException {
627653

628654
@Test
629655
public void testSummaryEmptyData() throws IOException {
656+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
630657
// SummaryData can be present but empty (no count, no sum, no quantiles).
631658
// This should be treated like no data is present.
632659
SummarySnapshot summary = SummarySnapshot.builder()
@@ -665,6 +692,7 @@ public void testSummaryEmptyAndNonEmpty() throws IOException {
665692
"} " +
666693
"}";
667694
//@formatter:on
695+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
668696
SummarySnapshot summary = SummarySnapshot.builder()
669697
.name("latency_seconds")
670698
.dataPoint(SummaryDataPointSnapshot.builder()
@@ -710,6 +738,7 @@ public void testSummaryWithDots() throws IOException {
710738
"summary { sample_count: 1 sample_sum: 0.03 } " +
711739
"}";
712740
//@formatter:on
741+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
713742

714743
SummarySnapshot summary = SummarySnapshot.builder()
715744
.name("my.request.duration.seconds")
@@ -831,6 +860,7 @@ public void testClassicHistogramComplete() throws Exception {
831860
"} " +
832861
"}";
833862
//@formatter:on
863+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
834864
HistogramSnapshot histogram = HistogramSnapshot.builder()
835865
.name("response_size_bytes")
836866
.help("help")
@@ -892,6 +922,7 @@ public void testClassicHistogramMinimal() throws Exception {
892922
"} " +
893923
"}";
894924
//@formatter:on
925+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
895926
HistogramSnapshot histogram = HistogramSnapshot.builder()
896927
.name("request_latency_seconds")
897928
.dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder()
@@ -935,6 +966,7 @@ public void testClassicHistogramCountAndSum() throws Exception {
935966
"} " +
936967
"}";
937968
//@formatter:on
969+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
938970
HistogramSnapshot histogram = HistogramSnapshot.builder()
939971
.name("request_latency_seconds")
940972
.dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder()
@@ -1054,6 +1086,7 @@ public void testClassicGaugeHistogramComplete() throws IOException {
10541086
"} " +
10551087
"}";
10561088
//@formatter:on
1089+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
10571090
HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder()
10581091
.gaugeHistogram(true)
10591092
.name("cache_size_bytes")
@@ -1117,6 +1150,7 @@ public void testClassicGaugeHistogramMinimal() throws IOException {
11171150
"} " +
11181151
"}";
11191152
//@formatter:on
1153+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
11201154
HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder()
11211155
.gaugeHistogram(true)
11221156
.name("queue_size_bytes")
@@ -1163,6 +1197,7 @@ public void testClassicGaugeHistogramCountAndSum() throws IOException {
11631197
"} " +
11641198
"}";
11651199
//@formatter:on
1200+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
11661201
HistogramSnapshot gaugeHistogram = HistogramSnapshot.builder()
11671202
.gaugeHistogram(true)
11681203
.name("queue_size_bytes")
@@ -1210,6 +1245,7 @@ public void testClassicHistogramWithDots() throws IOException {
12101245
"} " +
12111246
"}";
12121247
//@formatter:on
1248+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
12131249

12141250
HistogramSnapshot histogram = HistogramSnapshot.builder()
12151251
.name("my.request.duration.seconds")
@@ -1337,6 +1373,7 @@ public void testNativeHistogramComplete() throws IOException {
13371373
"} " +
13381374
"}";
13391375
//@formatter:on
1376+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
13401377
HistogramSnapshot nativeHistogram = HistogramSnapshot.builder()
13411378
.name("response_size_bytes")
13421379
.help("help")
@@ -1417,6 +1454,7 @@ public void testNativeHistogramMinimal() throws IOException {
14171454
"} " +
14181455
"}";
14191456
//@formatter:on
1457+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
14201458
HistogramSnapshot nativeHistogram = HistogramSnapshot.builder()
14211459
.name("latency_seconds")
14221460
.dataPoint(HistogramSnapshot.HistogramDataPointSnapshot.builder()
@@ -1463,6 +1501,7 @@ public void testNativeHistogramWithDots() throws IOException {
14631501
"} " +
14641502
"}";
14651503
//@formatter:on
1504+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
14661505

14671506
HistogramSnapshot histogram = HistogramSnapshot.builder()
14681507
.name("my.request.duration.seconds")
@@ -1499,6 +1538,7 @@ public void testInfo() throws IOException {
14991538
"# HELP version_info version information\n" +
15001539
"# TYPE version_info gauge\n" +
15011540
"version_info{version=\"1.2.3\"} 1\n";
1541+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
15021542
InfoSnapshot info = InfoSnapshot.builder()
15031543
.name("version")
15041544
.help("version information")
@@ -1533,6 +1573,7 @@ public void testInfoWithDots() throws IOException {
15331573
"gauge { value: 1.0 } " +
15341574
"}";
15351575
//@formatter:on
1576+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
15361577
InfoSnapshot info = InfoSnapshot.builder()
15371578
.name("jvm.status")
15381579
.help("JVM status info")
@@ -1562,6 +1603,7 @@ public void testStateSetComplete() throws IOException {
15621603
"state{env=\"dev\",state=\"state2\"} 0 " + scrapeTimestamp1s + "\n" +
15631604
"state{env=\"prod\",state=\"state1\"} 0 " + scrapeTimestamp2s + "\n" +
15641605
"state{env=\"prod\",state=\"state2\"} 1 " + scrapeTimestamp2s + "\n";
1606+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
15651607
StateSetSnapshot stateSet = StateSetSnapshot.builder()
15661608
.name("state")
15671609
.help("complete state set example")
@@ -1595,6 +1637,7 @@ public void testStateSetMinimal() throws IOException {
15951637
"# TYPE state gauge\n" +
15961638
"state{state=\"a\"} 1\n" +
15971639
"state{state=\"bb\"} 0\n";
1640+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
15981641
StateSetSnapshot stateSet = StateSetSnapshot.builder()
15991642
.name("state")
16001643
.dataPoint(StateSetSnapshot.StateSetDataPointSnapshot.builder()
@@ -1636,6 +1679,7 @@ public void testStateSetWithDots() throws IOException {
16361679
"gauge { value: 0.0 } " +
16371680
"}";
16381681
//@formatter:on
1682+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
16391683
StateSetSnapshot stateSet = StateSetSnapshot.builder()
16401684
.name("my.application.state")
16411685
.help("My application state")
@@ -1664,6 +1708,7 @@ public void testUnknownComplete() throws IOException {
16641708
"# TYPE my_special_thing_bytes untyped\n" +
16651709
"my_special_thing_bytes{env=\"dev\"} 0.2 " + scrapeTimestamp1s + "\n" +
16661710
"my_special_thing_bytes{env=\"prod\"} 0.7 " + scrapeTimestamp2s + "\n";
1711+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
16671712
UnknownSnapshot unknown = UnknownSnapshot.builder()
16681713
.name("my_special_thing_bytes")
16691714
.help("help message")
@@ -1696,6 +1741,7 @@ public void testUnknownMinimal() throws IOException {
16961741
String prometheus = "" +
16971742
"# TYPE other untyped\n" +
16981743
"other 22.3\n";
1744+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
16991745
UnknownSnapshot unknown = UnknownSnapshot.builder()
17001746
.name("other")
17011747
.dataPoint(UnknownDataPointSnapshot.builder()
@@ -1730,6 +1776,7 @@ public void testUnknownWithDots() throws IOException {
17301776
"untyped { value: 0.7 } " +
17311777
"}";
17321778
//@formatter:on
1779+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
17331780
UnknownSnapshot unknown = UnknownSnapshot.builder()
17341781
.name("some.unknown.metric")
17351782
.help("help message")
@@ -1756,6 +1803,7 @@ public void testHelpEscape() throws IOException {
17561803
"# HELP test_total Some text and \\n some \" escaping\n" +
17571804
"# TYPE test_total counter\n" +
17581805
"test_total 1.0\n";
1806+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
17591807
CounterSnapshot counter = CounterSnapshot.builder()
17601808
.name("test")
17611809
.help("Some text and \n some \" escaping") // example from https://openMetrics.io
@@ -1776,6 +1824,7 @@ public void testLabelValueEscape() throws IOException {
17761824
String prometheus = "" +
17771825
"# TYPE test_total counter\n" +
17781826
"test_total{a=\"x\",b=\"escaping\\\" example \\n \"} 1.0\n";
1827+
PrometheusNaming.nameValidationScheme = ValidationScheme.LegacyValidation;
17791828
CounterSnapshot counter = CounterSnapshot.builder()
17801829
.name("test")
17811830
.dataPoint(CounterDataPointSnapshot.builder()

0 commit comments

Comments
 (0)