Skip to content

Commit 7f26b67

Browse files
shakuzenmhalbritter
authored andcommitted
Auto-config support for latest Prometheus client and simpleclient
Deprecates the support for simpleclient but ensures that it can work in conjunction with support for the latest Prometheus client auto-configuration. This involves breaking changes to update public classes to support the latest Prometheus client. Deprecated support for Prometheus simpleclient is provided in renamed classes. See gh-40023
1 parent 2de9969 commit 7f26b67

File tree

31 files changed

+2332
-318
lines changed

31 files changed

+2332
-318
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ dependencies {
5353
optional("io.micrometer:micrometer-registry-kairos")
5454
optional("io.micrometer:micrometer-registry-new-relic")
5555
optional("io.micrometer:micrometer-registry-otlp")
56+
optional("io.micrometer:micrometer-registry-prometheus")
5657
optional("io.micrometer:micrometer-registry-prometheus-simpleclient")
5758
optional("io.micrometer:micrometer-registry-stackdriver") {
5859
exclude group: "commons-logging", module: "commons-logging"
@@ -141,6 +142,7 @@ dependencies {
141142
testImplementation(project(":spring-boot-project:spring-boot-tools:spring-boot-test-support"))
142143
testImplementation("io.micrometer:micrometer-observation-test")
143144
testImplementation("io.projectreactor:reactor-test")
145+
testImplementation("io.prometheus:prometheus-metrics-exposition-formats")
144146
testImplementation("io.r2dbc:r2dbc-h2")
145147
testImplementation("com.squareup.okhttp3:mockwebserver")
146148
testImplementation("com.jayway.jsonpath:json-path")

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusMetricsExportAutoConfiguration.java

Lines changed: 16 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,28 @@
1616

1717
package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus;
1818

19-
import java.net.MalformedURLException;
20-
import java.net.URL;
21-
import java.time.Duration;
22-
import java.util.Map;
23-
2419
import io.micrometer.core.instrument.Clock;
25-
import io.prometheus.client.CollectorRegistry;
26-
import io.prometheus.client.exemplars.DefaultExemplarSampler;
27-
import io.prometheus.client.exemplars.ExemplarSampler;
28-
import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier;
29-
import io.prometheus.client.exporter.BasicAuthHttpConnectionFactory;
30-
import io.prometheus.client.exporter.PushGateway;
20+
import io.micrometer.prometheusmetrics.PrometheusConfig;
21+
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
22+
import io.prometheus.metrics.model.registry.PrometheusRegistry;
23+
import io.prometheus.metrics.tracer.common.SpanContext;
3124

3225
import org.springframework.beans.factory.ObjectProvider;
3326
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
3427
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
3528
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
3629
import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport;
3730
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
38-
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager;
39-
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager.ShutdownOperation;
4031
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint;
32+
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusSimpleclientScrapeEndpoint;
4133
import org.springframework.boot.autoconfigure.AutoConfiguration;
4234
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
4335
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
4436
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
4537
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
46-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
4738
import org.springframework.boot.context.properties.EnableConfigurationProperties;
4839
import org.springframework.context.annotation.Bean;
4940
import org.springframework.context.annotation.Configuration;
50-
import org.springframework.core.env.Environment;
51-
import org.springframework.util.StringUtils;
5241

5342
/**
5443
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Prometheus.
@@ -58,98 +47,43 @@
5847
* @author Jonatan Ivanov
5948
* @since 2.0.0
6049
*/
61-
@SuppressWarnings("deprecation")
6250
@AutoConfiguration(
6351
before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class },
6452
after = MetricsAutoConfiguration.class)
6553
@ConditionalOnBean(Clock.class)
66-
@ConditionalOnClass(io.micrometer.prometheus.PrometheusMeterRegistry.class)
54+
@ConditionalOnClass(PrometheusMeterRegistry.class)
6755
@ConditionalOnEnabledMetricsExport("prometheus")
6856
@EnableConfigurationProperties(PrometheusProperties.class)
6957
public class PrometheusMetricsExportAutoConfiguration {
7058

7159
@Bean
7260
@ConditionalOnMissingBean
73-
public io.micrometer.prometheus.PrometheusConfig prometheusConfig(PrometheusProperties prometheusProperties) {
61+
public PrometheusConfig prometheusConfig(PrometheusProperties prometheusProperties) {
7462
return new PrometheusPropertiesConfigAdapter(prometheusProperties);
7563
}
7664

7765
@Bean
7866
@ConditionalOnMissingBean
79-
public io.micrometer.prometheus.PrometheusMeterRegistry prometheusMeterRegistry(
80-
io.micrometer.prometheus.PrometheusConfig prometheusConfig, CollectorRegistry collectorRegistry,
81-
Clock clock, ObjectProvider<ExemplarSampler> exemplarSamplerProvider) {
82-
return new io.micrometer.prometheus.PrometheusMeterRegistry(prometheusConfig, collectorRegistry, clock,
83-
exemplarSamplerProvider.getIfAvailable());
67+
public PrometheusMeterRegistry prometheusMeterRegistry(PrometheusConfig prometheusConfig,
68+
PrometheusRegistry prometheusRegistry, Clock clock, ObjectProvider<SpanContext> spanContext) {
69+
return new PrometheusMeterRegistry(prometheusConfig, prometheusRegistry, clock, spanContext.getIfAvailable());
8470
}
8571

8672
@Bean
8773
@ConditionalOnMissingBean
88-
public CollectorRegistry collectorRegistry() {
89-
return new CollectorRegistry(true);
90-
}
91-
92-
@Bean
93-
@ConditionalOnMissingBean(ExemplarSampler.class)
94-
@ConditionalOnBean(SpanContextSupplier.class)
95-
public DefaultExemplarSampler exemplarSampler(SpanContextSupplier spanContextSupplier) {
96-
return new DefaultExemplarSampler(spanContextSupplier);
74+
public PrometheusRegistry prometheusRegistry() {
75+
return new PrometheusRegistry();
9776
}
9877

9978
@Configuration(proxyBeanMethods = false)
10079
@ConditionalOnAvailableEndpoint(endpoint = PrometheusScrapeEndpoint.class)
10180
public static class PrometheusScrapeEndpointConfiguration {
10281

82+
@SuppressWarnings("removal")
10383
@Bean
104-
@ConditionalOnMissingBean
105-
public PrometheusScrapeEndpoint prometheusEndpoint(CollectorRegistry collectorRegistry) {
106-
return new PrometheusScrapeEndpoint(collectorRegistry);
107-
}
108-
109-
}
110-
111-
/**
112-
* Configuration for <a href="https://github.com/prometheus/pushgateway">Prometheus
113-
* Pushgateway</a>.
114-
*/
115-
@Configuration(proxyBeanMethods = false)
116-
@ConditionalOnClass(PushGateway.class)
117-
@ConditionalOnProperty(prefix = "management.prometheus.metrics.export.pushgateway", name = "enabled")
118-
public static class PrometheusPushGatewayConfiguration {
119-
120-
/**
121-
* The fallback job name. We use 'spring' since there's a history of Prometheus
122-
* spring integration defaulting to that name from when Prometheus integration
123-
* didn't exist in Spring itself.
124-
*/
125-
private static final String FALLBACK_JOB = "spring";
126-
127-
@Bean
128-
@ConditionalOnMissingBean
129-
public PrometheusPushGatewayManager prometheusPushGatewayManager(CollectorRegistry collectorRegistry,
130-
PrometheusProperties prometheusProperties, Environment environment) throws MalformedURLException {
131-
PrometheusProperties.Pushgateway properties = prometheusProperties.getPushgateway();
132-
Duration pushRate = properties.getPushRate();
133-
String job = getJob(properties, environment);
134-
Map<String, String> groupingKey = properties.getGroupingKey();
135-
ShutdownOperation shutdownOperation = properties.getShutdownOperation();
136-
PushGateway pushGateway = initializePushGateway(properties.getBaseUrl());
137-
if (StringUtils.hasText(properties.getUsername())) {
138-
pushGateway.setConnectionFactory(
139-
new BasicAuthHttpConnectionFactory(properties.getUsername(), properties.getPassword()));
140-
}
141-
return new PrometheusPushGatewayManager(pushGateway, collectorRegistry, pushRate, job, groupingKey,
142-
shutdownOperation);
143-
}
144-
145-
private PushGateway initializePushGateway(String url) throws MalformedURLException {
146-
return new PushGateway(new URL(url));
147-
}
148-
149-
private String getJob(PrometheusProperties.Pushgateway properties, Environment environment) {
150-
String job = properties.getJob();
151-
job = (job != null) ? job : environment.getProperty("spring.application.name");
152-
return (job != null) ? job : FALLBACK_JOB;
84+
@ConditionalOnMissingBean({ PrometheusScrapeEndpoint.class, PrometheusSimpleclientScrapeEndpoint.class })
85+
public PrometheusScrapeEndpoint prometheusEndpoint(PrometheusRegistry prometheusRegistry) {
86+
return new PrometheusScrapeEndpoint(prometheusRegistry);
15387
}
15488

15589
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusProperties.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
* @author Stephane Nicoll
3232
* @since 2.0.0
3333
*/
34-
@SuppressWarnings("deprecation")
3534
@ConfigurationProperties(prefix = "management.prometheus.metrics.export")
3635
public class PrometheusProperties {
3736

@@ -55,7 +54,13 @@ public class PrometheusProperties {
5554
/**
5655
* Histogram type for backing DistributionSummary and Timer.
5756
*/
58-
private io.micrometer.prometheus.HistogramFlavor histogramFlavor = io.micrometer.prometheus.HistogramFlavor.Prometheus;
57+
@Deprecated(since = "3.3.0")
58+
private HistogramFlavor histogramFlavor = HistogramFlavor.Prometheus;
59+
60+
/**
61+
* Additional properties to pass to the Prometheus client.
62+
*/
63+
private final Map<String, String> prometheusProperties = new HashMap<>();
5964

6065
/**
6166
* Step size (i.e. reporting frequency) to use.
@@ -70,11 +75,11 @@ public void setDescriptions(boolean descriptions) {
7075
this.descriptions = descriptions;
7176
}
7277

73-
public io.micrometer.prometheus.HistogramFlavor getHistogramFlavor() {
78+
public HistogramFlavor getHistogramFlavor() {
7479
return this.histogramFlavor;
7580
}
7681

77-
public void setHistogramFlavor(io.micrometer.prometheus.HistogramFlavor histogramFlavor) {
82+
public void setHistogramFlavor(HistogramFlavor histogramFlavor) {
7883
this.histogramFlavor = histogramFlavor;
7984
}
8085

@@ -98,6 +103,10 @@ public Pushgateway getPushgateway() {
98103
return this.pushgateway;
99104
}
100105

106+
public Map<String, String> getPrometheusProperties() {
107+
return this.prometheusProperties;
108+
}
109+
101110
/**
102111
* Configuration options for push-based interaction with Prometheus.
103112
*/
@@ -209,4 +218,13 @@ public void setShutdownOperation(ShutdownOperation shutdownOperation) {
209218

210219
}
211220

221+
public enum HistogramFlavor {
222+
223+
Prometheus, VictoriaMetrics;
224+
225+
HistogramFlavor() {
226+
}
227+
228+
}
229+
212230
}

spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/metrics/export/prometheus/PrometheusPropertiesConfigAdapter.java

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,21 @@
1717
package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus;
1818

1919
import java.time.Duration;
20+
import java.util.Map;
21+
import java.util.Properties;
22+
23+
import io.micrometer.prometheusmetrics.PrometheusConfig;
2024

2125
import org.springframework.boot.actuate.autoconfigure.metrics.export.properties.PropertiesConfigAdapter;
2226

2327
/**
24-
* Adapter to convert {@link PrometheusProperties} to a
25-
* {@link io.micrometer.prometheus.PrometheusConfig}.
28+
* Adapter to convert {@link PrometheusProperties} to a {@link PrometheusConfig}.
2629
*
2730
* @author Jon Schneider
2831
* @author Phillip Webb
2932
*/
30-
@SuppressWarnings("deprecation")
3133
class PrometheusPropertiesConfigAdapter extends PropertiesConfigAdapter<PrometheusProperties>
32-
implements io.micrometer.prometheus.PrometheusConfig {
34+
implements PrometheusConfig {
3335

3436
PrometheusPropertiesConfigAdapter(PrometheusProperties properties) {
3537
super(properties);
@@ -47,18 +49,28 @@ public String get(String key) {
4749

4850
@Override
4951
public boolean descriptions() {
50-
return get(PrometheusProperties::isDescriptions, io.micrometer.prometheus.PrometheusConfig.super::descriptions);
52+
return get(PrometheusProperties::isDescriptions, PrometheusConfig.super::descriptions);
5153
}
5254

5355
@Override
54-
public io.micrometer.prometheus.HistogramFlavor histogramFlavor() {
55-
return get(PrometheusProperties::getHistogramFlavor,
56-
io.micrometer.prometheus.PrometheusConfig.super::histogramFlavor);
56+
public Duration step() {
57+
return get(PrometheusProperties::getStep, PrometheusConfig.super::step);
5758
}
5859

5960
@Override
60-
public Duration step() {
61-
return get(PrometheusProperties::getStep, io.micrometer.prometheus.PrometheusConfig.super::step);
61+
public Properties prometheusProperties() {
62+
return get(this::fromPropertiesMap, PrometheusConfig.super::prometheusProperties);
63+
}
64+
65+
private Properties fromPropertiesMap(PrometheusProperties prometheusProperties) {
66+
Map<String, String> map = prometheusProperties.getPrometheusProperties();
67+
if (map.isEmpty()) {
68+
return null;
69+
}
70+
Properties properties = PrometheusConfig.super.prometheusProperties();
71+
properties = (properties != null) ? properties : new Properties();
72+
properties.putAll(map);
73+
return properties;
6274
}
6375

6476
}

0 commit comments

Comments
 (0)