001package io.prometheus.metrics.model.snapshots; 002 003import io.prometheus.metrics.config.EscapingScheme; 004import java.util.ArrayList; 005import java.util.List; 006import javax.annotation.Nullable; 007 008public class SnapshotEscaper { 009 010 private SnapshotEscaper() {} 011 012 /** Escapes the given metric names and labels with the given escaping scheme. */ 013 public static MetricSnapshot escapeMetricSnapshot(MetricSnapshot v, EscapingScheme scheme) { 014 if (scheme == EscapingScheme.ALLOW_UTF8 || scheme == EscapingScheme.UNDERSCORE_ESCAPING) { 015 // we re-use the prometheus name for underscore escaping as an optimization 016 return v; 017 } 018 019 List<DataPointSnapshot> outDataPoints = new ArrayList<>(); 020 021 for (DataPointSnapshot d : v.getDataPoints()) { 022 if (snapshotNeedsEscaping(d, scheme)) { 023 outDataPoints.add(d.escape(scheme)); 024 } else { 025 outDataPoints.add(d); 026 } 027 } 028 029 return v.escape(scheme, outDataPoints); 030 } 031 032 static boolean snapshotNeedsEscaping(DataPointSnapshot d, EscapingScheme scheme) { 033 Labels labels = d.getLabels(); 034 if (labelsNeedsEscaping(labels, scheme)) { 035 return true; 036 } 037 if (d instanceof SummarySnapshot.SummaryDataPointSnapshot) { 038 return exemplarsNeedsEscaping( 039 ((SummarySnapshot.SummaryDataPointSnapshot) d).getExemplars(), scheme); 040 } 041 if (d instanceof HistogramSnapshot.HistogramDataPointSnapshot) { 042 return exemplarsNeedsEscaping( 043 ((HistogramSnapshot.HistogramDataPointSnapshot) d).getExemplars(), scheme); 044 } 045 if (d instanceof CounterSnapshot.CounterDataPointSnapshot) { 046 return exemplarNeedsEscaping( 047 ((CounterSnapshot.CounterDataPointSnapshot) d).getExemplar(), scheme); 048 } 049 if (d instanceof UnknownSnapshot.UnknownDataPointSnapshot) { 050 return exemplarNeedsEscaping( 051 ((UnknownSnapshot.UnknownDataPointSnapshot) d).getExemplar(), scheme); 052 } 053 if (d instanceof GaugeSnapshot.GaugeDataPointSnapshot) { 054 return exemplarNeedsEscaping( 055 ((GaugeSnapshot.GaugeDataPointSnapshot) d).getExemplar(), scheme); 056 } 057 058 return false; 059 } 060 061 private static boolean labelsNeedsEscaping(Labels labels, EscapingScheme scheme) { 062 for (Label l : labels) { 063 if (PrometheusNaming.needsEscaping(l.getName(), scheme)) { 064 return true; 065 } 066 } 067 return false; 068 } 069 070 private static boolean exemplarNeedsEscaping(@Nullable Exemplar exemplar, EscapingScheme scheme) { 071 return exemplar != null && labelsNeedsEscaping(exemplar.getLabels(), scheme); 072 } 073 074 private static boolean exemplarsNeedsEscaping(Exemplars exemplars, EscapingScheme scheme) { 075 for (Exemplar exemplar : exemplars) { 076 if (labelsNeedsEscaping(exemplar.getLabels(), scheme)) { 077 return true; 078 } 079 } 080 return false; 081 } 082 083 public static String getSnapshotLabelName(Labels labels, int index, EscapingScheme scheme) { 084 if (scheme == EscapingScheme.UNDERSCORE_ESCAPING) { 085 return labels.getPrometheusName(index); 086 } else { 087 return labels.getName(index); 088 } 089 } 090 091 public static String getMetadataName(MetricMetadata metadata, EscapingScheme scheme) { 092 if (scheme == EscapingScheme.UNDERSCORE_ESCAPING) { 093 return metadata.getPrometheusName(); 094 } else { 095 return metadata.getName(); 096 } 097 } 098 099 public static Labels escapeLabels(Labels labels, EscapingScheme scheme) { 100 Labels.Builder outLabelsBuilder = Labels.builder(); 101 102 for (Label l : labels) { 103 outLabelsBuilder.label(PrometheusNaming.escapeName(l.getName(), scheme), l.getValue()); 104 } 105 106 return outLabelsBuilder.build(); 107 } 108 109 public static Exemplars escapeExemplars(Exemplars exemplars, EscapingScheme scheme) { 110 List<Exemplar> escapedExemplars = new ArrayList<>(exemplars.size()); 111 for (Exemplar exemplar : exemplars) { 112 escapedExemplars.add(escapeExemplar(exemplar, scheme)); 113 } 114 return Exemplars.of(escapedExemplars); 115 } 116 117 @Nullable 118 public static Exemplar escapeExemplar(@Nullable Exemplar exemplar, EscapingScheme scheme) { 119 if (exemplar == null) { 120 return null; 121 } 122 return Exemplar.builder() 123 .labels(escapeLabels(exemplar.getLabels(), scheme)) 124 .timestampMillis(exemplar.getTimestampMillis()) 125 .value(exemplar.getValue()) 126 .build(); 127 } 128}