Fix broken content negotiation for Prometheus with OpenMetrics
Update Prometheus `TextOutputFormat` so that OpenMetrics is used in preference to text output when an appropriate accept header is found. If the accept header contains `*/*` or is missing then the text format will be used. See gh-28130
This commit is contained in:
parent
d8141e6a8d
commit
437a1601ef
|
|
@ -35,18 +35,6 @@ import org.springframework.util.MimeTypeUtils;
|
||||||
*/
|
*/
|
||||||
public enum TextOutputFormat implements Producible<TextOutputFormat> {
|
public enum TextOutputFormat implements Producible<TextOutputFormat> {
|
||||||
|
|
||||||
/**
|
|
||||||
* OpenMetrics text version 1.0.0.
|
|
||||||
*/
|
|
||||||
CONTENT_TYPE_OPENMETRICS_100(TextFormat.CONTENT_TYPE_OPENMETRICS_100) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void write(Writer writer, Enumeration<MetricFamilySamples> samples) throws IOException {
|
|
||||||
TextFormat.writeOpenMetrics100(writer, samples);
|
|
||||||
}
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prometheus text version 0.0.4.
|
* Prometheus text version 0.0.4.
|
||||||
*/
|
*/
|
||||||
|
|
@ -57,6 +45,23 @@ public enum TextOutputFormat implements Producible<TextOutputFormat> {
|
||||||
TextFormat.write004(writer, samples);
|
TextFormat.write004(writer, samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDefault() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenMetrics text version 1.0.0.
|
||||||
|
*/
|
||||||
|
CONTENT_TYPE_OPENMETRICS_100(TextFormat.CONTENT_TYPE_OPENMETRICS_100) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void write(Writer writer, Enumeration<MetricFamilySamples> samples) throws IOException {
|
||||||
|
TextFormat.writeOpenMetrics100(writer, samples);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private final MimeType mimeType;
|
private final MimeType mimeType;
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,14 @@ class PrometheusScrapeEndpointIntegrationTests {
|
||||||
.contains("counter1_total").contains("counter2_total").contains("counter3_total"));
|
.contains("counter1_total").contains("counter2_total").contains("counter3_total"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WebEndpointTest
|
||||||
|
void scrapePrefersToProduceOpenMetrics100(WebTestClient client) {
|
||||||
|
MediaType openMetrics = MediaType.parseMediaType(TextFormat.CONTENT_TYPE_OPENMETRICS_100);
|
||||||
|
MediaType textPlain = MediaType.parseMediaType(TextFormat.CONTENT_TYPE_004);
|
||||||
|
client.get().uri("/actuator/prometheus").accept(openMetrics, textPlain).exchange().expectStatus().isOk()
|
||||||
|
.expectHeader().contentType(openMetrics);
|
||||||
|
}
|
||||||
|
|
||||||
@WebEndpointTest
|
@WebEndpointTest
|
||||||
void scrapeWithIncludedNames(WebTestClient client) {
|
void scrapeWithIncludedNames(WebTestClient client) {
|
||||||
client.get().uri("/actuator/prometheus?includedNames=counter1_total,counter2_total").exchange().expectStatus()
|
client.get().uri("/actuator/prometheus?includedNames=counter1_total,counter2_total").exchange().expectStatus()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue