Skip to content

Commit 5699469

Browse files
authored
fix: Tighten OM2 summary and start timestamp output (#2041)
1 parent d2196a7 commit 5699469

2 files changed

Lines changed: 41 additions & 40 deletions

File tree

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

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import io.prometheus.metrics.model.snapshots.CounterSnapshot;
1616
import io.prometheus.metrics.model.snapshots.DataPointSnapshot;
1717
import io.prometheus.metrics.model.snapshots.Exemplar;
18+
import io.prometheus.metrics.model.snapshots.Exemplars;
1819
import io.prometheus.metrics.model.snapshots.GaugeSnapshot;
1920
import io.prometheus.metrics.model.snapshots.HistogramSnapshot;
2021
import io.prometheus.metrics.model.snapshots.InfoSnapshot;
@@ -62,7 +63,7 @@ public Builder setOpenMetrics2Properties(OpenMetrics2Properties openMetrics2Prop
6263
}
6364

6465
/**
65-
* @param createdTimestampsEnabled whether to include the _created timestamp in the output
66+
* @param createdTimestampsEnabled whether to include the start timestamp in the output
6667
*/
6768
public Builder setCreatedTimestampsEnabled(boolean createdTimestampsEnabled) {
6869
this.createdTimestampsEnabled = createdTimestampsEnabled;
@@ -93,8 +94,7 @@ public OpenMetrics2TextFormatWriter build() {
9394

9495
/**
9596
* @param openMetrics2Properties OpenMetrics 2.0 feature flags
96-
* @param createdTimestampsEnabled whether to include the _created timestamp in the output - This
97-
* will produce an invalid OpenMetrics output, but is kept for backwards compatibility.
97+
* @param createdTimestampsEnabled whether to include the start timestamp in the output.
9898
* @param exemplarsOnAllMetricTypesEnabled whether to include exemplars on all metric types
9999
*/
100100
public OpenMetrics2TextFormatWriter(
@@ -177,8 +177,16 @@ private void writeCounter(Writer writer, CounterSnapshot snapshot, EscapingSchem
177177
for (CounterSnapshot.CounterDataPointSnapshot data : snapshot.getDataPoints()) {
178178
writeNameAndLabels(writer, counterName, null, data.getLabels(), scheme);
179179
writeDouble(writer, data.getValue());
180-
writeScrapeTimestampAndExemplar(writer, data, data.getExemplar(), scheme);
181-
writeCreated(writer, counterName, data, scheme);
180+
if (data.hasScrapeTimestamp()) {
181+
writer.write(' ');
182+
writeOpenMetricsTimestamp(writer, data.getScrapeTimestampMillis());
183+
}
184+
if (createdTimestampsEnabled && data.hasCreatedTimestamp()) {
185+
writer.write(" st@");
186+
writeOpenMetricsTimestamp(writer, data.getCreatedTimestampMillis());
187+
}
188+
writeExemplar(writer, data.getExemplar(), scheme);
189+
writer.write('\n');
182190
}
183191
}
184192

@@ -316,22 +324,20 @@ private void writeCompositeSummaryDataPoint(
316324
writeDouble(writer, data.getSum());
317325
first = false;
318326
}
319-
if (data.getQuantiles().size() > 0) {
320-
if (!first) {
327+
if (!first) {
328+
writer.write(',');
329+
}
330+
writer.write("quantile:[");
331+
for (int i = 0; i < data.getQuantiles().size(); i++) {
332+
if (i > 0) {
321333
writer.write(',');
322334
}
323-
writer.write("quantile:[");
324-
for (int i = 0; i < data.getQuantiles().size(); i++) {
325-
if (i > 0) {
326-
writer.write(',');
327-
}
328-
Quantile q = data.getQuantiles().get(i);
329-
writeDouble(writer, q.getQuantile());
330-
writer.write(':');
331-
writeDouble(writer, q.getValue());
332-
}
333-
writer.write(']');
335+
Quantile q = data.getQuantiles().get(i);
336+
writeDouble(writer, q.getQuantile());
337+
writer.write(':');
338+
writeDouble(writer, q.getValue());
334339
}
340+
writer.write(']');
335341
writer.write('}');
336342
if (data.hasScrapeTimestamp()) {
337343
writer.write(' ');
@@ -341,7 +347,7 @@ private void writeCompositeSummaryDataPoint(
341347
writer.write(" st@");
342348
writeOpenMetricsTimestamp(writer, data.getCreatedTimestampMillis());
343349
}
344-
writeExemplar(writer, data.getExemplars().getLatest(), scheme);
350+
writeExemplars(writer, data.getExemplars(), scheme);
345351
writer.write('\n');
346352
}
347353

@@ -411,20 +417,6 @@ private void writeUnknown(Writer writer, UnknownSnapshot snapshot, EscapingSchem
411417
}
412418
}
413419

414-
private void writeCreated(
415-
Writer writer, String name, DataPointSnapshot data, EscapingScheme scheme)
416-
throws IOException {
417-
if (createdTimestampsEnabled && data.hasCreatedTimestamp()) {
418-
writeNameAndLabels(writer, name, "_created", data.getLabels(), scheme);
419-
writeOpenMetricsTimestamp(writer, data.getCreatedTimestampMillis());
420-
if (data.hasScrapeTimestamp()) {
421-
writer.write(' ');
422-
writeOpenMetricsTimestamp(writer, data.getScrapeTimestampMillis());
423-
}
424-
writer.write('\n');
425-
}
426-
}
427-
428420
private void writeNameAndLabels(
429421
Writer writer,
430422
String name,
@@ -496,6 +488,13 @@ private void writeExemplar(Writer writer, @Nullable Exemplar exemplar, EscapingS
496488
}
497489
}
498490

491+
private void writeExemplars(Writer writer, Exemplars exemplars, EscapingScheme scheme)
492+
throws IOException {
493+
for (Exemplar exemplar : exemplars) {
494+
writeExemplar(writer, exemplar, scheme);
495+
}
496+
}
497+
499498
private void writeMetadataWithName(
500499
Writer writer, String name, String typeName, MetricMetadata metadata) throws IOException {
501500
writer.write("# TYPE ");

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,12 @@ void testCounterWithCreatedTimestamps() throws IOException {
307307

308308
String om2Output = write(snapshots, om2Writer);
309309

310-
// OM2: no _total, _created uses the counter name directly
310+
// OM2: no _total, start timestamp uses st@ inline.
311311
assertThat(om2Output)
312312
.isEqualTo(
313313
"# TYPE my_counter counter\n"
314314
+ "# HELP my_counter Test counter\n"
315-
+ "my_counter 42.0\n"
316-
+ "my_counter_created 1672850385.800\n"
315+
+ "my_counter 42.0 st@1672850385.800\n"
317316
+ "# EOF\n");
318317
}
319318

@@ -479,8 +478,10 @@ void testCompositeSummary() throws IOException {
479478

480479
@Test
481480
void testCompositeSummaryWithCreatedAndExemplar() throws IOException {
482-
Exemplar exemplar =
481+
Exemplar exemplar1 =
483482
Exemplar.builder().value(0.5).traceId("abc123").timestampMillis(1520879607000L).build();
483+
Exemplar exemplar2 =
484+
Exemplar.builder().value(1.5).traceId("def456").timestampMillis(1520879608000L).build();
484485

485486
MetricSnapshots snapshots =
486487
MetricSnapshots.of(
@@ -491,7 +492,7 @@ void testCompositeSummaryWithCreatedAndExemplar() throws IOException {
491492
.count(10)
492493
.sum(100.0)
493494
.createdTimestampMillis(1520430000000L)
494-
.exemplars(Exemplars.of(exemplar))
495+
.exemplars(Exemplars.of(exemplar1, exemplar2))
495496
.build())
496497
.build());
497498

@@ -500,8 +501,9 @@ void testCompositeSummaryWithCreatedAndExemplar() throws IOException {
500501
assertThat(output)
501502
.isEqualTo(
502503
"# TYPE rpc_duration_seconds summary\n"
503-
+ "rpc_duration_seconds {count:10,sum:100.0} st@1520430000.000"
504-
+ " # {trace_id=\"abc123\"} 0.5 1520879607.000\n"
504+
+ "rpc_duration_seconds {count:10,sum:100.0,quantile:[]} st@1520430000.000"
505+
+ " # {trace_id=\"abc123\"} 0.5 1520879607.000"
506+
+ " # {trace_id=\"def456\"} 1.5 1520879608.000\n"
505507
+ "# EOF\n");
506508
}
507509

0 commit comments

Comments
 (0)