Skip to content

Support OpenMetrics text format in Prometheus Actuator endpoint #25564

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
shakuzen opened this issue Mar 10, 2021 · 0 comments
Closed

Support OpenMetrics text format in Prometheus Actuator endpoint #25564

shakuzen opened this issue Mar 10, 2021 · 0 comments
Assignees
Labels
type: enhancement A general enhancement
Milestone

Comments

@shakuzen
Copy link
Member

OpenMetrics has been finalized and the Prometheus Java client supports the OpenMetrics data model and text scrape format since its 0.10.0 release. It would be nice if the Prometheus Actuator endpoint could respond with the Prometheus text format or the OpenMetrics text format based on the Accept header sent, using HTTP content negotiation.

I made an attempt to implement this, but I couldn't figure out a way to do HTTP content negotiation and keep the current portability of the endpoint. It already is a web-only endpoint, but it works on Jersey. Switching to a RestControllerEndpoint, I was able to achieve the right behavior, except Jersey is not supported.

@GetMapping(produces = {TextFormat.CONTENT_TYPE_004, TextFormat.CONTENT_TYPE_OPENMETRICS_100})
public ResponseEntity<String> scrape(@RequestParam(name = "includedNames", required = false) Set<String> includedNames,
									 @RequestHeader(name = "Accept", required = false) String acceptHeader) {
	try {
		Writer writer = new StringWriter();
		Enumeration<MetricFamilySamples> samples = (includedNames != null)
				? this.collectorRegistry.filteredMetricFamilySamples(includedNames)
				: this.collectorRegistry.metricFamilySamples();
		String contentType = TextFormat.chooseContentType(acceptHeader);
		TextFormat.writeFormat(contentType, writer, samples);
		return ResponseEntity.ok().contentType(MediaType.valueOf(contentType)).body(writer.toString());
	}
	catch (IOException ex) {
		// This actually never happens since StringWriter::write() doesn't throw any
		// IOException
		throw new RuntimeException("Writing metrics failed", ex);
	}
}

A generic ReadOperation can specify the types it produces (so it rejects requests with unsupported Accept headers), but it has no access to the Accept header to change the returned content based on it. I'm not sure what the Boot team wants to do, which is why I opted to open an issue over a pull request with the above (also, I wasn't sure of an easy way to test a RestControllerEndpoint similar to how the current WebEndpoint is tested).

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Mar 10, 2021
@philwebb philwebb added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 10, 2021
@philwebb philwebb added this to the 2.5.x milestone Mar 10, 2021
@wilkinsona wilkinsona self-assigned this Mar 18, 2021
@philwebb philwebb self-assigned this Mar 19, 2021
philwebb pushed a commit that referenced this issue Mar 19, 2021
Update `PrometheusScrapeEndpoint` so that it can produce both classic
Prometheus text output as well as Openmetrics output.

See gh-25564
@philwebb philwebb modified the milestones: 2.5.x, 2.5.0-M3 Mar 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

4 participants