Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,14 @@ include::{snippets}/prometheus/curl-request.adoc[]
The resulting response is similar to the following:

include::{snippets}/prometheus/http-response.adoc[]



[[prometheus-retrieving-query-parameters]]
=== Query Parameters

The endpoint uses query parameters to limit the samples that it returns.
The following table shows the supported query parameters:

[cols="2,4"]
include::{snippets}/prometheus/request-parameters.adoc[]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -28,13 +28,16 @@
import org.springframework.context.annotation.Import;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.requestParameters;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

/**
* Tests for generating documentation describing the {@link PrometheusScrapeEndpoint}.
*
* @author Andy Wilkinson
* @author Johnny Lim
*/
class PrometheusScrapeEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {

Expand All @@ -43,6 +46,16 @@ void prometheus() throws Exception {
this.mockMvc.perform(get("/actuator/prometheus")).andExpect(status().isOk()).andDo(document("prometheus"));
}

@Test
void filteredPrometheus() throws Exception {
this.mockMvc
.perform(get("/actuator/prometheus").param("includedNames",
"jvm_memory_used_bytes,jvm_memory_committed_bytes"))
.andExpect(status().isOk())
.andDo(document("prometheus", requestParameters(parameterWithName("includedNames")
.description("Restricts the samples to those that match the names. Optional.").optional())));
}

@Configuration(proxyBeanMethods = false)
@Import(BaseDocumentationConfiguration.class)
static class TestConfiguration {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,19 +19,24 @@
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Set;

import io.prometheus.client.Collector.MetricFamilySamples;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.common.TextFormat;

import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
import org.springframework.boot.actuate.endpoint.web.annotation.WebEndpoint;
import org.springframework.lang.Nullable;

/**
* {@link Endpoint @Endpoint} that outputs metrics in a format that can be scraped by the
* Prometheus server.
*
* @author Jon Schneider
* @author Johnny Lim
* @since 2.0.0
*/
@WebEndpoint(id = "prometheus")
Expand All @@ -44,10 +49,13 @@ public PrometheusScrapeEndpoint(CollectorRegistry collectorRegistry) {
}

@ReadOperation(produces = TextFormat.CONTENT_TYPE_004)
public String scrape() {
public String scrape(@Nullable Set<String> includedNames) {
try {
Writer writer = new StringWriter();
TextFormat.write004(writer, this.collectorRegistry.metricFamilySamples());
Enumeration<MetricFamilySamples> samples = (includedNames != null)
? this.collectorRegistry.filteredMetricFamilySamples(includedNames)
: this.collectorRegistry.metricFamilySamples();
TextFormat.write004(writer, samples);
return writer.toString();
}
catch (IOException ex) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@
package org.springframework.boot.actuate.metrics.export.prometheus;

import io.micrometer.core.instrument.Clock;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.CollectorRegistry;
Expand All @@ -28,17 +29,30 @@
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Tests for {@link PrometheusScrapeEndpoint}.
*
* @author Jon Schneider
* @author Johnny Lim
*/
class PrometheusScrapeEndpointIntegrationTests {

@WebEndpointTest
void scrapeHasContentTypeText004(WebTestClient client) {
client.get().uri("/actuator/prometheus").exchange().expectStatus().isOk().expectHeader()
.contentType(MediaType.parseMediaType(TextFormat.CONTENT_TYPE_004));
.contentType(MediaType.parseMediaType(TextFormat.CONTENT_TYPE_004)).expectBody(String.class)
.value((body) -> assertThat(body).contains("counter1_total").contains("counter2_total")
.contains("counter3_total"));
}

@WebEndpointTest
void scrapeWithIncludedNames(WebTestClient client) {
client.get().uri("/actuator/prometheus?includedNames=counter1_total,counter2_total").exchange().expectStatus()
.isOk().expectHeader().contentType(MediaType.parseMediaType(TextFormat.CONTENT_TYPE_004))
.expectBody(String.class).value((body) -> assertThat(body).contains("counter1_total")
.contains("counter2_total").doesNotContain("counter3_total"));
}

@Configuration(proxyBeanMethods = false)
Expand All @@ -56,7 +70,11 @@ CollectorRegistry collectorRegistry() {

@Bean
MeterRegistry registry(CollectorRegistry registry) {
return new PrometheusMeterRegistry((k) -> null, registry, Clock.SYSTEM);
PrometheusMeterRegistry meterRegistry = new PrometheusMeterRegistry((k) -> null, registry, Clock.SYSTEM);
Counter.builder("counter1").register(meterRegistry);
Counter.builder("counter2").register(meterRegistry);
Counter.builder("counter3").register(meterRegistry);
return meterRegistry;
}

}
Expand Down