Skip to content

Commit fcd41f4

Browse files
committed
Merge pull request #40023 from shakuzen
* pr/40023: Polish "Auto-config support for latest Prometheus client and simpleclient" Auto-config support for latest Prometheus client and simpleclient Closes gh-40023
2 parents 2de9969 + ce358c6 commit fcd41f4

File tree

32 files changed

+2344
-324
lines changed

32 files changed

+2344
-324
lines changed

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

+2
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

+17-83
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+
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+
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+
PrometheusRegistry prometheusRegistry() {
75+
return new PrometheusRegistry();
9776
}
9877

9978
@Configuration(proxyBeanMethods = false)
10079
@ConditionalOnAvailableEndpoint(endpoint = PrometheusScrapeEndpoint.class)
101-
public static class PrometheusScrapeEndpointConfiguration {
102-
103-
@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";
80+
static class PrometheusScrapeEndpointConfiguration {
12681

82+
@SuppressWarnings("removal")
12783
@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+
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

+29-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager.ShutdownOperation;
2424
import org.springframework.boot.context.properties.ConfigurationProperties;
25+
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
2526

2627
/**
2728
* {@link ConfigurationProperties @ConfigurationProperties} for configuring metrics export
@@ -31,7 +32,6 @@
3132
* @author Stephane Nicoll
3233
* @since 2.0.0
3334
*/
34-
@SuppressWarnings("deprecation")
3535
@ConfigurationProperties(prefix = "management.prometheus.metrics.export")
3636
public class PrometheusProperties {
3737

@@ -55,7 +55,13 @@ public class PrometheusProperties {
5555
/**
5656
* Histogram type for backing DistributionSummary and Timer.
5757
*/
58-
private io.micrometer.prometheus.HistogramFlavor histogramFlavor = io.micrometer.prometheus.HistogramFlavor.Prometheus;
58+
@Deprecated(since = "3.3.0", forRemoval = true)
59+
private HistogramFlavor histogramFlavor = HistogramFlavor.Prometheus;
60+
61+
/**
62+
* Additional properties to pass to the Prometheus client.
63+
*/
64+
private final Map<String, String> properties = new HashMap<>();
5965

6066
/**
6167
* Step size (i.e. reporting frequency) to use.
@@ -70,11 +76,14 @@ public void setDescriptions(boolean descriptions) {
7076
this.descriptions = descriptions;
7177
}
7278

73-
public io.micrometer.prometheus.HistogramFlavor getHistogramFlavor() {
79+
@Deprecated(since = "3.3.0", forRemoval = true)
80+
@DeprecatedConfigurationProperty(since = "3.3.0",
81+
reason = "No longer supported. Works only when using the Prometheus simpleclient.")
82+
public HistogramFlavor getHistogramFlavor() {
7483
return this.histogramFlavor;
7584
}
7685

77-
public void setHistogramFlavor(io.micrometer.prometheus.HistogramFlavor histogramFlavor) {
86+
public void setHistogramFlavor(HistogramFlavor histogramFlavor) {
7887
this.histogramFlavor = histogramFlavor;
7988
}
8089

@@ -98,6 +107,10 @@ public Pushgateway getPushgateway() {
98107
return this.pushgateway;
99108
}
100109

110+
public Map<String, String> getProperties() {
111+
return this.properties;
112+
}
113+
101114
/**
102115
* Configuration options for push-based interaction with Prometheus.
103116
*/
@@ -209,4 +222,16 @@ public void setShutdownOperation(ShutdownOperation shutdownOperation) {
209222

210223
}
211224

225+
/**
226+
* Prometheus Histogram flavor.
227+
*
228+
* @deprecated since 3.3.0 for removal in 3.5.0
229+
*/
230+
@Deprecated(since = "3.3.0", forRemoval = true)
231+
public enum HistogramFlavor {
232+
233+
Prometheus, VictoriaMetrics;
234+
235+
}
236+
212237
}

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

+22-10
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.getProperties();
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)