Skip to content

Commit a210cb8

Browse files
committed
prepare move snapshot escaper
Signed-off-by: Gregor Zeitlinger <[email protected]>
1 parent d4d4516 commit a210cb8

File tree

9 files changed

+170
-176
lines changed

9 files changed

+170
-176
lines changed

prometheus-metrics-exporter-pushgateway/src/main/java/io/prometheus/metrics/exporter/pushgateway/PushGateway.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package io.prometheus.metrics.exporter.pushgateway;
22

33
import static io.prometheus.metrics.exporter.pushgateway.Scheme.HTTP;
4-
import static io.prometheus.metrics.model.snapshots.SnapshotEscaper.escapeName;
4+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.escapeName;
55

66
import io.prometheus.metrics.config.ExporterPushgatewayProperties;
77
import io.prometheus.metrics.config.PrometheusProperties;

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public void write(
6464
}
6565
}
6666

67-
Metrics.MetricFamily convert(MetricSnapshot snapshot, EscapingScheme scheme) {
67+
public Metrics.MetricFamily convert(MetricSnapshot snapshot, EscapingScheme scheme) {
6868
Metrics.MetricFamily.Builder builder = Metrics.MetricFamily.newBuilder();
6969
if (snapshot instanceof CounterSnapshot) {
7070
for (CounterDataPointSnapshot data : ((CounterSnapshot) snapshot).getDataPoints()) {
@@ -136,7 +136,8 @@ private Metrics.Metric.Builder convert(CounterDataPointSnapshot data, EscapingSc
136136
return metricBuilder;
137137
}
138138

139-
private Metrics.Metric.Builder convert(GaugeSnapshot.GaugeDataPointSnapshot data, EscapingScheme scheme) {
139+
private Metrics.Metric.Builder convert(
140+
GaugeSnapshot.GaugeDataPointSnapshot data, EscapingScheme scheme) {
140141
Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder();
141142
gaugeBuilder.setValue(data.getValue());
142143
Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder();
@@ -202,7 +203,8 @@ private Metrics.Metric.Builder convert(
202203
return metricBuilder;
203204
}
204205

205-
private Metrics.Metric.Builder convert(SummarySnapshot.SummaryDataPointSnapshot data, EscapingScheme scheme) {
206+
private Metrics.Metric.Builder convert(
207+
SummarySnapshot.SummaryDataPointSnapshot data, EscapingScheme scheme) {
206208
Metrics.Summary.Builder summaryBuilder = Metrics.Summary.newBuilder();
207209
if (data.hasCount()) {
208210
summaryBuilder.setSampleCount(data.getCount());
@@ -225,7 +227,8 @@ private Metrics.Metric.Builder convert(SummarySnapshot.SummaryDataPointSnapshot
225227
return metricBuilder;
226228
}
227229

228-
private Metrics.Metric.Builder convert(InfoSnapshot.InfoDataPointSnapshot data, EscapingScheme scheme) {
230+
private Metrics.Metric.Builder convert(
231+
InfoSnapshot.InfoDataPointSnapshot data, EscapingScheme scheme) {
229232
Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder();
230233
Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder();
231234
gaugeBuilder.setValue(1);
@@ -236,7 +239,7 @@ private Metrics.Metric.Builder convert(InfoSnapshot.InfoDataPointSnapshot data,
236239
}
237240

238241
private Metrics.Metric.Builder convert(
239-
StateSetSnapshot.StateSetDataPointSnapshot data, String name, int i, EscapingScheme scheme) {
242+
StateSetSnapshot.StateSetDataPointSnapshot data, String name, int i, EscapingScheme scheme) {
240243
Metrics.Metric.Builder metricBuilder = Metrics.Metric.newBuilder();
241244
Metrics.Gauge.Builder gaugeBuilder = Metrics.Gauge.newBuilder();
242245
addLabels(metricBuilder, data.getLabels(), scheme);

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import io.prometheus.metrics.expositionformats.internal.ProtobufUtil;
88
import io.prometheus.metrics.model.snapshots.EscapingScheme;
99
import io.prometheus.metrics.model.snapshots.MetricSnapshot;
10-
import io.prometheus.metrics.model.snapshots.PrometheusNaming;
1110
import io.prometheus.metrics.model.snapshots.SnapshotEscaper;
1211

1312
class ProtobufExpositionFormatsTest extends ExpositionFormatsTest {
@@ -17,7 +16,7 @@ protected void assertPrometheusProtobuf(String expected, MetricSnapshot snapshot
1716
PrometheusProtobufWriterImpl writer = new PrometheusProtobufWriterImpl();
1817
Metrics.MetricFamily protobufData =
1918
writer.convert(
20-
SnapshotEscaper.escapeMetricSnapshot(snapshot, EscapingScheme.UNDERSCORE_ESCAPING));
19+
snapshot, EscapingScheme.UNDERSCORE_ESCAPING);
2120
String actual = ProtobufUtil.shortDebugString(protobufData);
2221
assertThat(actual).isEqualTo(expected);
2322
}

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ private void writeCounter(Writer writer, CounterSnapshot snapshot, EscapingSchem
175175
MetricMetadata metadata = snapshot.getMetadata();
176176
writeMetadata(writer, "_total", "counter", metadata, scheme);
177177
for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) {
178-
writeNameAndLabels(writer, getMetadataName(metadata, scheme), "_total", data.getLabels(), scheme);
178+
writeNameAndLabels(
179+
writer, getMetadataName(metadata, scheme), "_total", data.getLabels(), scheme);
179180
writeDouble(writer, data.getValue());
180181
writeScrapeTimestampAndNewline(writer, data);
181182
}
@@ -397,12 +398,7 @@ private void writeNameAndLabels(
397398
writeName(writer, name + (suffix != null ? suffix : ""), NameType.Metric);
398399
if (!labels.isEmpty() || additionalLabelName != null) {
399400
writeLabels(
400-
writer,
401-
labels,
402-
additionalLabelName,
403-
additionalLabelValue,
404-
metricInsideBraces,
405-
scheme);
401+
writer, labels, additionalLabelName, additionalLabelValue, metricInsideBraces, scheme);
406402
} else if (metricInsideBraces) {
407403
writer.write('}');
408404
}

prometheus-metrics-exposition-textformats/src/main/java/io/prometheus/metrics/expositionformats/TextFormatUtil.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import io.prometheus.metrics.model.snapshots.Labels;
55
import io.prometheus.metrics.model.snapshots.PrometheusNaming;
66
import io.prometheus.metrics.model.snapshots.SnapshotEscaper;
7-
87
import java.io.IOException;
98
import java.io.Writer;
109

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

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

3+
import static java.lang.Character.MAX_CODE_POINT;
4+
import static java.lang.Character.MAX_LOW_SURROGATE;
5+
import static java.lang.Character.MIN_HIGH_SURROGATE;
6+
37
import java.nio.charset.StandardCharsets;
48
import java.util.regex.Pattern;
59

@@ -147,7 +151,7 @@ public static String validateUnitName(String name) {
147151
* @return the name with dots replaced by underscores.
148152
*/
149153
public static String prometheusName(String name) {
150-
return SnapshotEscaper.escapeName(name, EscapingScheme.UNDERSCORE_ESCAPING);
154+
return escapeName(name, EscapingScheme.UNDERSCORE_ESCAPING);
151155
}
152156

153157
/**
@@ -267,4 +271,85 @@ private static String replaceIllegalCharsInUnitName(String name) {
267271
}
268272
return new String(sanitized);
269273
}
274+
275+
/**
276+
* Escapes the incoming name according to the provided escaping scheme. Depending on the rules of
277+
* escaping, this may cause no change in the string that is returned (especially NO_ESCAPING,
278+
* which by definition is a noop). This method does not do any validation of the name.
279+
*/
280+
public static String escapeName(String name, EscapingScheme scheme) {
281+
if (name.isEmpty() || !needsEscaping(name, scheme)) {
282+
return name;
283+
}
284+
285+
StringBuilder escaped = new StringBuilder();
286+
switch (scheme) {
287+
case NO_ESCAPING:
288+
return name;
289+
case UNDERSCORE_ESCAPING:
290+
for (int i = 0; i < name.length(); ) {
291+
int c = name.codePointAt(i);
292+
if (isValidLegacyChar(c, i)) {
293+
escaped.appendCodePoint(c);
294+
} else {
295+
escaped.append('_');
296+
}
297+
i += Character.charCount(c);
298+
}
299+
return escaped.toString();
300+
case DOTS_ESCAPING:
301+
// Do not early return for legacy valid names, we still escape underscores.
302+
for (int i = 0; i < name.length(); ) {
303+
int c = name.codePointAt(i);
304+
if (c == '_') {
305+
escaped.append("__");
306+
} else if (c == '.') {
307+
escaped.append("_dot_");
308+
} else if (isValidLegacyChar(c, i)) {
309+
escaped.appendCodePoint(c);
310+
} else {
311+
escaped.append("__");
312+
}
313+
i += Character.charCount(c);
314+
}
315+
return escaped.toString();
316+
case VALUE_ENCODING_ESCAPING:
317+
escaped.append("U__");
318+
for (int i = 0; i < name.length(); ) {
319+
int c = name.codePointAt(i);
320+
if (c == '_') {
321+
escaped.append("__");
322+
} else if (isValidLegacyChar(c, i)) {
323+
escaped.appendCodePoint(c);
324+
} else if (!isValidUtf8Char(c)) {
325+
escaped.append("_FFFD_");
326+
} else {
327+
escaped.append('_');
328+
escaped.append(Integer.toHexString(c));
329+
escaped.append('_');
330+
}
331+
i += Character.charCount(c);
332+
}
333+
return escaped.toString();
334+
default:
335+
throw new IllegalArgumentException("Invalid escaping scheme " + scheme);
336+
}
337+
}
338+
339+
public static boolean needsEscaping(String name, EscapingScheme scheme) {
340+
return !isValidLegacyMetricName(name)
341+
|| (scheme == EscapingScheme.DOTS_ESCAPING && (name.contains(".") || name.contains("_")));
342+
}
343+
344+
static boolean isValidLegacyChar(int c, int i) {
345+
return (c >= 'a' && c <= 'z')
346+
|| (c >= 'A' && c <= 'Z')
347+
|| c == '_'
348+
|| c == ':'
349+
|| (c >= '0' && c <= '9' && i > 0);
350+
}
351+
352+
private static boolean isValidUtf8Char(int c) {
353+
return (0 <= c && c < MIN_HIGH_SURROGATE) || (MAX_LOW_SURROGATE < c && c <= MAX_CODE_POINT);
354+
}
270355
}

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

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

3-
import static java.lang.Character.MAX_CODE_POINT;
4-
import static java.lang.Character.MAX_LOW_SURROGATE;
5-
import static java.lang.Character.MIN_HIGH_SURROGATE;
6-
73
import java.util.ArrayList;
84
import java.util.List;
95
import javax.annotation.Nullable;
@@ -14,7 +10,8 @@ private SnapshotEscaper() {}
1410

1511
/** Escapes the given metric names and labels with the given escaping scheme. */
1612
@Nullable
17-
public static MetricSnapshot escapeMetricSnapshot(@Nullable MetricSnapshot v, EscapingScheme scheme) {
13+
public static MetricSnapshot escapeMetricSnapshot(
14+
@Nullable MetricSnapshot v, EscapingScheme scheme) {
1815
if (v == null) {
1916
return null;
2017
}
@@ -37,7 +34,7 @@ public static MetricSnapshot escapeMetricSnapshot(@Nullable MetricSnapshot v, Es
3734
}
3835

3936
return createEscapedMetricSnapshot(
40-
v, escapeName(v.getMetadata().getName(), scheme), outDataPoints);
37+
v, PrometheusNaming.escapeName(v.getMetadata().getName(), scheme), outDataPoints);
4138
}
4239

4340
static MetricSnapshot createEscapedMetricSnapshot(
@@ -116,7 +113,7 @@ private static Labels escapeLabels(Labels labels, EscapingScheme scheme) {
116113
Labels.Builder outLabelsBuilder = Labels.builder();
117114

118115
for (Label l : labels) {
119-
outLabelsBuilder.label(escapeName(l.getName(), scheme), l.getValue());
116+
outLabelsBuilder.label(PrometheusNaming.escapeName(l.getName(), scheme), l.getValue());
120117
}
121118

122119
return outLabelsBuilder.build();
@@ -153,7 +150,7 @@ static boolean snapshotNeedsEscaping(DataPointSnapshot d, EscapingScheme scheme)
153150

154151
private static boolean labelsNeedsEscaping(Labels labels, EscapingScheme scheme) {
155152
for (Label l : labels) {
156-
if (needsEscaping(l.getName(), scheme)) {
153+
if (PrometheusNaming.needsEscaping(l.getName(), scheme)) {
157154
return true;
158155
}
159156
}
@@ -273,87 +270,6 @@ private static Exemplar escapeExemplar(@Nullable Exemplar exemplar, EscapingSche
273270
.build();
274271
}
275272

276-
/**
277-
* Escapes the incoming name according to the provided escaping scheme. Depending on the rules of
278-
* escaping, this may cause no change in the string that is returned (especially NO_ESCAPING,
279-
* which by definition is a noop). This method does not do any validation of the name.
280-
*/
281-
public static String escapeName(String name, EscapingScheme scheme) {
282-
if (name.isEmpty() || !needsEscaping(name, scheme)) {
283-
return name;
284-
}
285-
286-
StringBuilder escaped = new StringBuilder();
287-
switch (scheme) {
288-
case NO_ESCAPING:
289-
return name;
290-
case UNDERSCORE_ESCAPING:
291-
for (int i = 0; i < name.length(); ) {
292-
int c = name.codePointAt(i);
293-
if (isValidLegacyChar(c, i)) {
294-
escaped.appendCodePoint(c);
295-
} else {
296-
escaped.append('_');
297-
}
298-
i += Character.charCount(c);
299-
}
300-
return escaped.toString();
301-
case DOTS_ESCAPING:
302-
// Do not early return for legacy valid names, we still escape underscores.
303-
for (int i = 0; i < name.length(); ) {
304-
int c = name.codePointAt(i);
305-
if (c == '_') {
306-
escaped.append("__");
307-
} else if (c == '.') {
308-
escaped.append("_dot_");
309-
} else if (isValidLegacyChar(c, i)) {
310-
escaped.appendCodePoint(c);
311-
} else {
312-
escaped.append("__");
313-
}
314-
i += Character.charCount(c);
315-
}
316-
return escaped.toString();
317-
case VALUE_ENCODING_ESCAPING:
318-
escaped.append("U__");
319-
for (int i = 0; i < name.length(); ) {
320-
int c = name.codePointAt(i);
321-
if (c == '_') {
322-
escaped.append("__");
323-
} else if (isValidLegacyChar(c, i)) {
324-
escaped.appendCodePoint(c);
325-
} else if (!isValidUtf8Char(c)) {
326-
escaped.append("_FFFD_");
327-
} else {
328-
escaped.append('_');
329-
escaped.append(Integer.toHexString(c));
330-
escaped.append('_');
331-
}
332-
i += Character.charCount(c);
333-
}
334-
return escaped.toString();
335-
default:
336-
throw new IllegalArgumentException("Invalid escaping scheme " + scheme);
337-
}
338-
}
339-
340-
public static boolean needsEscaping(String name, EscapingScheme scheme) {
341-
return !PrometheusNaming.isValidLegacyMetricName(name)
342-
|| (scheme == EscapingScheme.DOTS_ESCAPING && (name.contains(".") || name.contains("_")));
343-
}
344-
345-
static boolean isValidLegacyChar(int c, int i) {
346-
return (c >= 'a' && c <= 'z')
347-
|| (c >= 'A' && c <= 'Z')
348-
|| c == '_'
349-
|| c == ':'
350-
|| (c >= '0' && c <= '9' && i > 0);
351-
}
352-
353-
private static boolean isValidUtf8Char(int c) {
354-
return (0 <= c && c < MIN_HIGH_SURROGATE) || (MAX_LOW_SURROGATE < c && c <= MAX_CODE_POINT);
355-
}
356-
357273
public static String getSnapshotLabelName(Labels labels, int index, EscapingScheme scheme) {
358274
if (scheme == EscapingScheme.UNDERSCORE_ESCAPING) {
359275
return labels.getPrometheusName(index);

0 commit comments

Comments
 (0)