Skip to content

Commit add7c1e

Browse files
committed
Add logic for handling content negotation flag with OM2
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
1 parent 6beb7fd commit add7c1e

2 files changed

Lines changed: 87 additions & 3 deletions

File tree

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

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,17 @@ public ExpositionFormatWriter findWriter(@Nullable String acceptHeader) {
6363
return prometheusProtobufWriter;
6464
}
6565

66-
// Prefer OM2 over OM1 when any OM2 feature is enabled
6766
if (isOpenMetrics2Enabled() && openMetrics2TextFormatWriter.accepts(acceptHeader)) {
68-
return openMetrics2TextFormatWriter;
67+
if (openMetrics2TextFormatWriter.getOpenMetrics2Properties().getContentNegotiation()) {
68+
String version = parseOpenMetricsVersion(acceptHeader);
69+
if ("2.0.0".equals(version)) {
70+
return openMetrics2TextFormatWriter;
71+
}
72+
// version=1.0.0 or no version: fall through to OM1
73+
} else {
74+
// contentNegotiation=false: OM2 handles all OpenMetrics requests
75+
return openMetrics2TextFormatWriter;
76+
}
6977
}
7078

7179
if (openMetricsTextFormatWriter.accepts(acceptHeader)) {
@@ -94,4 +102,22 @@ public OpenMetricsTextFormatWriter getOpenMetricsTextFormatWriter() {
94102
public OpenMetrics2TextFormatWriter getOpenMetrics2TextFormatWriter() {
95103
return openMetrics2TextFormatWriter;
96104
}
105+
106+
@Nullable
107+
private static String parseOpenMetricsVersion(@Nullable String acceptHeader) {
108+
if (acceptHeader == null) {
109+
return null;
110+
}
111+
for (String mediaType : acceptHeader.split(";")) {
112+
String[] tokens = mediaType.split("=");
113+
if (tokens.length == 2) {
114+
String key = tokens[0].trim();
115+
String value = tokens[1].trim();
116+
if (key.equals("version")) {
117+
return value;
118+
}
119+
}
120+
}
121+
return null;
122+
}
97123
}

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ void testOM2EnabledWithFeatureFlags() {
155155
.build())
156156
.build();
157157
ExpositionFormats formats = ExpositionFormats.init(props);
158-
ExpositionFormatWriter writer = formats.findWriter("application/openmetrics-text");
158+
ExpositionFormatWriter writer =
159+
formats.findWriter("application/openmetrics-text; version=2.0.0");
159160
assertThat(writer).isInstanceOf(OpenMetrics2TextFormatWriter.class);
160161
}
161162

@@ -173,6 +174,63 @@ void testProtobufWriterTakesPrecedence() {
173174
assertThat(writer).isInstanceOf(PrometheusProtobufWriter.class);
174175
}
175176

177+
@Test
178+
void testOM2ContentNegotiationWithVersion2() {
179+
PrometheusProperties props =
180+
PrometheusProperties.builder()
181+
.openMetrics2Properties(
182+
OpenMetrics2Properties.builder().enabled(true).contentNegotiation(true).build())
183+
.build();
184+
ExpositionFormats formats = ExpositionFormats.init(props);
185+
ExpositionFormatWriter writer =
186+
formats.findWriter("application/openmetrics-text; version=2.0.0");
187+
assertThat(writer).isInstanceOf(OpenMetrics2TextFormatWriter.class);
188+
}
189+
190+
@Test
191+
void testOM2ContentNegotiationWithVersion1() {
192+
PrometheusProperties props =
193+
PrometheusProperties.builder()
194+
.openMetrics2Properties(
195+
OpenMetrics2Properties.builder().enabled(true).contentNegotiation(true).build())
196+
.build();
197+
ExpositionFormats formats = ExpositionFormats.init(props);
198+
ExpositionFormatWriter writer =
199+
formats.findWriter("application/openmetrics-text; version=1.0.0");
200+
assertThat(writer).isInstanceOf(OpenMetricsTextFormatWriter.class);
201+
}
202+
203+
@Test
204+
void testOM2ContentNegotiationWithNoVersion() {
205+
// When contentNegotiation=true and Accept header has no version, use OM1 writer
206+
PrometheusProperties props =
207+
PrometheusProperties.builder()
208+
.openMetrics2Properties(
209+
OpenMetrics2Properties.builder().enabled(true).contentNegotiation(true).build())
210+
.build();
211+
ExpositionFormats formats = ExpositionFormats.init(props);
212+
ExpositionFormatWriter writer = formats.findWriter("application/openmetrics-text");
213+
assertThat(writer).isInstanceOf(OpenMetricsTextFormatWriter.class);
214+
}
215+
216+
@Test
217+
void testOM2ContentNegotiationDisabled() {
218+
PrometheusProperties props =
219+
PrometheusProperties.builder()
220+
.openMetrics2Properties(
221+
OpenMetrics2Properties.builder().enabled(true).contentNegotiation(false).build())
222+
.build();
223+
ExpositionFormats formats = ExpositionFormats.init(props);
224+
ExpositionFormatWriter writer1 = formats.findWriter("application/openmetrics-text");
225+
ExpositionFormatWriter writer2 =
226+
formats.findWriter("application/openmetrics-text; version=1.0.0");
227+
ExpositionFormatWriter writer3 =
228+
formats.findWriter("application/openmetrics-text; version=2.0.0");
229+
assertThat(writer1).isInstanceOf(OpenMetrics2TextFormatWriter.class);
230+
assertThat(writer2).isInstanceOf(OpenMetrics2TextFormatWriter.class);
231+
assertThat(writer3).isInstanceOf(OpenMetrics2TextFormatWriter.class);
232+
}
233+
176234
@Test
177235
void testCounterComplete() throws IOException {
178236
String openMetricsText =

0 commit comments

Comments
 (0)