Skip to content

Commit b02837b

Browse files
authored
[bugfix] fix the prometheus metric response data parsing is abnormal (apache#3274)
1 parent 9f9cdcf commit b02837b

File tree

2 files changed

+54
-28
lines changed
  • hertzbeat-collector/hertzbeat-collector-basic/src

2 files changed

+54
-28
lines changed

hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/prometheus/parser/OnlineParser.java

+46-26
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@
3838
public class OnlineParser {
3939

4040
private static final Map<Integer, Integer> escapeMap = new HashMap<>(8);
41-
41+
42+
private static final char RIGHT_BRACKET = '}';
43+
private static final char LEFT_BRACKET = '{';
44+
4245
static {
4346
escapeMap.put((int) 'n', (int) '\n');
4447
escapeMap.put((int) 'b', (int) '\b');
@@ -94,14 +97,14 @@ private static class CharChecker {
9497
}
9598

9699
private CharChecker maybeLeftBracket() {
97-
if (i == '{') {
100+
if (i == LEFT_BRACKET) {
98101
satisfied = true;
99102
}
100103
return this;
101104
}
102105

103106
private CharChecker maybeRightBracket() {
104-
if (i == '}') {
107+
if (i == RIGHT_BRACKET) {
105108
satisfied = true;
106109
}
107110
return this;
@@ -264,35 +267,52 @@ private static Double toDouble(String string) throws FormatException {
264267
}
265268
}
266269

267-
private static CharChecker parseLabels(InputStream inputStream, StringBuilder stringBuilder, List<MetricFamily.Label> labelList) throws IOException, FormatException {
270+
271+
/**
272+
* parse single label like label_name="label_value"
273+
*/
274+
private static CharChecker parseLabel(InputStream inputStream, StringBuilder stringBuilder, List<MetricFamily.Label> labelList) throws IOException, FormatException {
268275
int i;
269-
while (true) {
270-
MetricFamily.Label label = new MetricFamily.Label();
271-
i = skipSpaces(inputStream).getInt();
272-
stringBuilder.append((char) i);
273-
i = parseLabelName(inputStream, stringBuilder).maybeSpace().maybeEqualsSign().noElse();
274-
label.setName(stringBuilder.toString());
275-
stringBuilder.delete(0, stringBuilder.length());
276-
if (i == ' ') {
277-
skipSpaces(inputStream).maybeEqualsSign().noElse();
278-
}
276+
MetricFamily.Label label = new MetricFamily.Label();
277+
i = skipSpaces(inputStream).getInt();
278+
if (i == RIGHT_BRACKET) {
279+
return new CharChecker(i);
280+
}
281+
stringBuilder.append((char) i);
282+
i = parseLabelName(inputStream, stringBuilder).maybeSpace().maybeEqualsSign().noElse();
283+
label.setName(stringBuilder.toString());
284+
stringBuilder.delete(0, stringBuilder.length());
285+
if (i == ' ') {
286+
skipSpaces(inputStream).maybeEqualsSign().noElse();
287+
}
288+
289+
skipSpaces(inputStream).maybeQuotationMark().noElse();
290+
parseLabelValue(inputStream, stringBuilder).maybeQuotationMark().noElse();
291+
String labelValue = stringBuilder.toString();
292+
if (!labelValue.equals(new String(labelValue.getBytes(StandardCharsets.UTF_8)))) {
293+
throw new FormatException();
294+
}
295+
label.setValue(labelValue);
296+
stringBuilder.delete(0, stringBuilder.length());
297+
labelList.add(label);
298+
return new CharChecker(i);
299+
}
279300

280-
skipSpaces(inputStream).maybeQuotationMark().noElse();
281-
parseLabelValue(inputStream, stringBuilder).maybeQuotationMark().noElse();
282-
String labelValue = stringBuilder.toString();
283-
if (!labelValue.equals(new String(labelValue.getBytes(StandardCharsets.UTF_8)))) {
284-
throw new FormatException();
285-
}
286-
label.setValue(labelValue);
287-
stringBuilder.delete(0, stringBuilder.length());
288301

302+
private static void parseLabels(InputStream inputStream, StringBuilder stringBuilder, List<MetricFamily.Label> labelList) throws IOException, FormatException {
303+
int i;
304+
while (true) {
305+
// deal with labels like {label1="aaa",label2=bbb",}
306+
CharChecker charChecker = parseLabel(inputStream, stringBuilder, labelList);
307+
if (charChecker.i == RIGHT_BRACKET) {
308+
return;
309+
}
310+
//deal with labels like {label1="aaa",label2=bbb"}
289311
i = skipSpaces(inputStream).maybeSpace().maybeComma().maybeRightBracket().noElse();
290-
labelList.add(label);
291-
if (i == '}') {
292-
break;
312+
if (i == RIGHT_BRACKET) {
313+
return;
293314
}
294315
}
295-
return new CharChecker(i);
296316
}
297317

298318
private static CharChecker parseMetric(InputStream inputStream, Map<String, MetricFamily> metricFamilyMap, StringBuilder stringBuilder) throws IOException, FormatException {

hertzbeat-collector/hertzbeat-collector-basic/src/test/java/org/apache/hertzbeat/collector/collect/prometheus/parser/OnlineParserTest.java

+8-2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ void parseMetrics2() throws Exception {
4848
String str = """
4949
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
5050
# TYPE go_gc_duration_seconds summary
51+
jvm_gc_pause_seconds_count{action="end of major GC",cause="Metadata GC Threshold",} 1.0
52+
jvm_gc_pause_seconds_sum{action="end of major GC",cause="Metadata GC Threshold",} 0.139
53+
jvm_gc_pause_seconds_count{action="end of minor GC",cause="Metadata GC Threshold",} 1.0
54+
jvm_gc_pause_seconds_sum{action="end of minor GC",cause="Metadata GC Threshold",} 0.02
55+
jvm_gc_pause_seconds_count{action="end of minor GC",cause="Allocation Failure",} 5.0
56+
jvm_gc_pause_seconds_sum{action="end of minor GC",cause="Allocation Failure",} 0.082
57+
go_gc_duration_seconds{quantile="0"} 2.0209e-05
5158
go_gc_duration_seconds{quantile="0"} 2.0209e-05
5259
go_gc_duration_seconds{quantile="0.25"} 6.6917e-05
5360
go_gc_duration_seconds{quantile="0.5"} -Inf
@@ -87,7 +94,6 @@ void parseMetrics2() throws Exception {
8794
fail("parse failed, different result from two parser.");
8895
}
8996
MetricFamily metricFamily1 = metricFamilyMap1.get(metricFamilyName);
90-
assertEquals(metricFamily1.getName(), metricFamily1.getName());
9197
Set<Double> metricValueSet = metricFamily2.getMetricList().stream().map(MetricFamily.Metric::getValue).collect(Collectors.toSet());
9298
metricFamily1.getMetricList().forEach(metric -> {
9399
// this is for something different between two algorithms above, and both of them is current on this parsing behavior.
@@ -99,4 +105,4 @@ void parseMetrics2() throws Exception {
99105
});
100106
});
101107
}
102-
}
108+
}

0 commit comments

Comments
 (0)