Skip to content

Commit e61f127

Browse files
committed
escape exemplars
Signed-off-by: Gregor Zeitlinger <[email protected]>
1 parent 842b993 commit e61f127

File tree

2 files changed

+88
-24
lines changed

2 files changed

+88
-24
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,10 @@
2828
import java.io.ByteArrayOutputStream;
2929
import java.io.IOException;
3030
import java.util.concurrent.atomic.AtomicInteger;
31-
import org.junit.jupiter.api.AfterEach;
31+
3232
import org.junit.jupiter.api.Test;
3333
import org.junit.jupiter.params.ParameterizedTest;
3434
import org.junit.jupiter.params.provider.CsvSource;
35-
import org.junitpioneer.jupiter.SetSystemProperty;
3635

3736
class ExpositionFormatsTest {
3837

prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java

Lines changed: 87 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.prometheus.metrics.model.snapshots;
22

3+
import javax.annotation.Nullable;
4+
35
import static java.lang.Character.MAX_CODE_POINT;
46
import static java.lang.Character.MAX_LOW_SURROGATE;
57
import static java.lang.Character.MIN_HIGH_SURROGATE;
@@ -288,28 +290,60 @@ public static MetricSnapshot escapeMetricSnapshot(MetricSnapshot v, EscapingSche
288290
List<DataPointSnapshot> outDataPoints = new ArrayList<>();
289291

290292
for (DataPointSnapshot d : v.getDataPoints()) {
291-
if (!metricNeedsEscaping(d, scheme)) {
293+
if (!snapshotNeedsEscaping(d, scheme)) {
292294
outDataPoints.add(d);
293295
continue;
294296
}
295297

296-
Labels.Builder outLabelsBuilder = Labels.builder();
297-
298-
for (Label l : d.getLabels()) {
299-
outLabelsBuilder.label(escapeName(l.getName(), scheme), l.getValue());
300-
}
301-
302-
Labels outLabels = outLabelsBuilder.build();
303-
DataPointSnapshot outDataPointSnapshot = createEscapedDataPointSnapshot(v, d, outLabels);
298+
DataPointSnapshot outDataPointSnapshot =
299+
createEscapedDataPointSnapshot(v, d, escapeLabels(d.getLabels(), scheme), scheme);
304300
outDataPoints.add(outDataPointSnapshot);
305301
}
306302

307303
return createEscapedMetricSnapshot(
308304
v, escapeName(v.getMetadata().getName(), scheme), outDataPoints);
309305
}
310306

311-
static boolean metricNeedsEscaping(DataPointSnapshot d, EscapingScheme scheme) {
307+
private static Labels escapeLabels(Labels labels, EscapingScheme scheme) {
308+
Labels.Builder outLabelsBuilder = Labels.builder();
309+
310+
for (Label l : labels) {
311+
outLabelsBuilder.label(escapeName(l.getName(), scheme), l.getValue());
312+
}
313+
314+
return outLabelsBuilder.build();
315+
}
316+
317+
static boolean snapshotNeedsEscaping(DataPointSnapshot d, EscapingScheme scheme) {
312318
Labels labels = d.getLabels();
319+
if (labelsNeedsEscaping(labels, scheme)) {
320+
return true;
321+
}
322+
if (d instanceof SummarySnapshot.SummaryDataPointSnapshot) {
323+
return exemplarsNeedsEscaping(
324+
((SummarySnapshot.SummaryDataPointSnapshot) d).getExemplars(), scheme);
325+
}
326+
if (d instanceof HistogramSnapshot.HistogramDataPointSnapshot) {
327+
return exemplarsNeedsEscaping(
328+
((HistogramSnapshot.HistogramDataPointSnapshot) d).getExemplars(), scheme);
329+
}
330+
if (d instanceof CounterSnapshot.CounterDataPointSnapshot) {
331+
return exemplarNeedsEscaping(
332+
((CounterSnapshot.CounterDataPointSnapshot) d).getExemplar(), scheme);
333+
}
334+
if (d instanceof UnknownSnapshot.UnknownDataPointSnapshot) {
335+
return exemplarNeedsEscaping(
336+
((UnknownSnapshot.UnknownDataPointSnapshot) d).getExemplar(), scheme);
337+
}
338+
if (d instanceof GaugeSnapshot.GaugeDataPointSnapshot) {
339+
return exemplarNeedsEscaping(
340+
((GaugeSnapshot.GaugeDataPointSnapshot) d).getExemplar(), scheme);
341+
}
342+
343+
return false;
344+
}
345+
346+
private static boolean labelsNeedsEscaping(Labels labels, EscapingScheme scheme) {
313347
for (Label l : labels) {
314348
if (needsEscaping(l.getName(), scheme)) {
315349
return true;
@@ -318,20 +352,35 @@ static boolean metricNeedsEscaping(DataPointSnapshot d, EscapingScheme scheme) {
318352
return false;
319353
}
320354

355+
private static boolean exemplarNeedsEscaping(@Nullable Exemplar exemplar, EscapingScheme scheme) {
356+
return exemplar != null && labelsNeedsEscaping(exemplar.getLabels(), scheme);
357+
}
358+
359+
private static boolean exemplarsNeedsEscaping(Exemplars exemplars, EscapingScheme scheme) {
360+
for (Exemplar exemplar : exemplars) {
361+
if (labelsNeedsEscaping(exemplar.getLabels(), scheme)) {
362+
return true;
363+
}
364+
}
365+
return false;
366+
}
367+
321368
private static DataPointSnapshot createEscapedDataPointSnapshot(
322-
MetricSnapshot v, DataPointSnapshot d, Labels outLabels) {
369+
MetricSnapshot v, DataPointSnapshot d, Labels outLabels, EscapingScheme scheme) {
323370
if (v instanceof CounterSnapshot) {
324371
return CounterSnapshot.CounterDataPointSnapshot.builder()
325372
.value(((CounterSnapshot.CounterDataPointSnapshot) d).getValue())
326-
.exemplar(((CounterSnapshot.CounterDataPointSnapshot) d).getExemplar())
373+
.exemplar(
374+
escapeExemplar(((CounterSnapshot.CounterDataPointSnapshot) d).getExemplar(), scheme))
327375
.labels(outLabels)
328376
.createdTimestampMillis(d.getCreatedTimestampMillis())
329377
.scrapeTimestampMillis(d.getScrapeTimestampMillis())
330378
.build();
331379
} else if (v instanceof GaugeSnapshot) {
332380
return GaugeSnapshot.GaugeDataPointSnapshot.builder()
333381
.value(((GaugeSnapshot.GaugeDataPointSnapshot) d).getValue())
334-
.exemplar(((GaugeSnapshot.GaugeDataPointSnapshot) d).getExemplar())
382+
.exemplar(
383+
escapeExemplar(((GaugeSnapshot.GaugeDataPointSnapshot) d).getExemplar(), scheme))
335384
.labels(outLabels)
336385
.scrapeTimestampMillis(d.getScrapeTimestampMillis())
337386
.build();
@@ -351,7 +400,9 @@ private static DataPointSnapshot createEscapedDataPointSnapshot(
351400
.getNativeBucketsForNegativeValues())
352401
.count(((HistogramSnapshot.HistogramDataPointSnapshot) d).getCount())
353402
.sum(((HistogramSnapshot.HistogramDataPointSnapshot) d).getSum())
354-
.exemplars(((HistogramSnapshot.HistogramDataPointSnapshot) d).getExemplars())
403+
.exemplars(
404+
escapeExemplars(
405+
((HistogramSnapshot.HistogramDataPointSnapshot) d).getExemplars(), scheme))
355406
.labels(outLabels)
356407
.createdTimestampMillis(d.getCreatedTimestampMillis())
357408
.scrapeTimestampMillis(d.getScrapeTimestampMillis())
@@ -361,7 +412,9 @@ private static DataPointSnapshot createEscapedDataPointSnapshot(
361412
.quantiles(((SummarySnapshot.SummaryDataPointSnapshot) d).getQuantiles())
362413
.count(((SummarySnapshot.SummaryDataPointSnapshot) d).getCount())
363414
.sum(((SummarySnapshot.SummaryDataPointSnapshot) d).getSum())
364-
.exemplars(((SummarySnapshot.SummaryDataPointSnapshot) d).getExemplars())
415+
.exemplars(
416+
escapeExemplars(
417+
((SummarySnapshot.SummaryDataPointSnapshot) d).getExemplars(), scheme))
365418
.labels(outLabels)
366419
.createdTimestampMillis(d.getCreatedTimestampMillis())
367420
.scrapeTimestampMillis(d.getScrapeTimestampMillis())
@@ -384,14 +437,32 @@ private static DataPointSnapshot createEscapedDataPointSnapshot(
384437
return UnknownSnapshot.UnknownDataPointSnapshot.builder()
385438
.labels(outLabels)
386439
.value(((UnknownSnapshot.UnknownDataPointSnapshot) d).getValue())
387-
.exemplar(((UnknownSnapshot.UnknownDataPointSnapshot) d).getExemplar())
440+
.exemplar(
441+
escapeExemplar(((UnknownSnapshot.UnknownDataPointSnapshot) d).getExemplar(), scheme))
388442
.scrapeTimestampMillis(d.getScrapeTimestampMillis())
389443
.build();
390444
} else {
391445
throw new IllegalArgumentException("Unknown MetricSnapshot type: " + v.getClass());
392446
}
393447
}
394448

449+
private static Exemplars escapeExemplars(Exemplars exemplars, EscapingScheme scheme) {
450+
List<Exemplar> escapedExemplars = new ArrayList<>(exemplars.size());
451+
for (Exemplar exemplar : exemplars) {
452+
Exemplar escaped = escapeExemplar(exemplar, scheme);
453+
escapedExemplars.add(escaped);
454+
}
455+
return Exemplars.of(escapedExemplars);
456+
}
457+
458+
private static Exemplar escapeExemplar(Exemplar exemplar, EscapingScheme scheme) {
459+
return Exemplar.builder()
460+
.labels(escapeLabels(exemplar.getLabels(), scheme))
461+
.timestampMillis(exemplar.getTimestampMillis())
462+
.value(exemplar.getValue())
463+
.build();
464+
}
465+
395466
private static MetricSnapshot createEscapedMetricSnapshot(
396467
MetricSnapshot v, String outName, List<DataPointSnapshot> outDataPoints) {
397468
if (v instanceof CounterSnapshot) {
@@ -479,9 +550,6 @@ public static String escapeName(String name, EscapingScheme scheme) {
479550
case NO_ESCAPING:
480551
return name;
481552
case UNDERSCORE_ESCAPING:
482-
if (isValidLegacyMetricName(name)) {
483-
return name;
484-
}
485553
for (int i = 0; i < name.length(); ) {
486554
int c = name.codePointAt(i);
487555
if (isValidLegacyChar(c, i)) {
@@ -509,9 +577,6 @@ public static String escapeName(String name, EscapingScheme scheme) {
509577
}
510578
return escaped.toString();
511579
case VALUE_ENCODING_ESCAPING:
512-
if (isValidLegacyMetricName(name)) {
513-
return name;
514-
}
515580
escaped.append("U__");
516581
for (int i = 0; i < name.length(); ) {
517582
int c = name.codePointAt(i);

0 commit comments

Comments
 (0)