11package io .prometheus .metrics .model .snapshots ;
22
3+ import javax .annotation .Nullable ;
4+
35import static java .lang .Character .MAX_CODE_POINT ;
46import static java .lang .Character .MAX_LOW_SURROGATE ;
57import 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