Skip to content

Commit

Permalink
Auto-config support for latest Prometheus client and simpleclient
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
shakuzen committed Mar 19, 2024
1 parent f99b536 commit 6d2f7b7
Show file tree
Hide file tree
Showing 27 changed files with 1,830 additions and 195 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ dependencies {
optional("io.micrometer:micrometer-registry-kairos")
optional("io.micrometer:micrometer-registry-new-relic")
optional("io.micrometer:micrometer-registry-otlp")
optional("io.micrometer:micrometer-registry-prometheus")
optional("io.micrometer:micrometer-registry-prometheus-simpleclient")
optional("io.micrometer:micrometer-registry-stackdriver") {
exclude group: "commons-logging", module: "commons-logging"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,26 @@

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

import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.Map;

import io.micrometer.core.instrument.Clock;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exemplars.DefaultExemplarSampler;
import io.prometheus.client.exemplars.ExemplarSampler;
import io.prometheus.client.exemplars.tracer.common.SpanContextSupplier;
import io.prometheus.client.exporter.BasicAuthHttpConnectionFactory;
import io.prometheus.client.exporter.PushGateway;
import io.micrometer.prometheusmetrics.PrometheusConfig;
import io.micrometer.prometheusmetrics.PrometheusMeterRegistry;
import io.prometheus.metrics.model.registry.PrometheusRegistry;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.ConditionalOnEnabledMetricsExport;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager.ShutdownOperation;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusSimpleclientScrapeEndpoint;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

/**
* {@link EnableAutoConfiguration Auto-configuration} for exporting metrics to Prometheus.
Expand All @@ -58,98 +45,44 @@
* @author Jonatan Ivanov
* @since 2.0.0
*/
@SuppressWarnings("deprecation")
@AutoConfiguration(
before = { CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class },
after = MetricsAutoConfiguration.class)
@ConditionalOnBean(Clock.class)
@ConditionalOnClass(io.micrometer.prometheus.PrometheusMeterRegistry.class)
@ConditionalOnClass(PrometheusMeterRegistry.class)
@ConditionalOnEnabledMetricsExport("prometheus")
@EnableConfigurationProperties(PrometheusProperties.class)
public class PrometheusMetricsExportAutoConfiguration {

@Bean
@ConditionalOnMissingBean
public io.micrometer.prometheus.PrometheusConfig prometheusConfig(PrometheusProperties prometheusProperties) {
public PrometheusConfig prometheusConfig(PrometheusProperties prometheusProperties) {
return new PrometheusPropertiesConfigAdapter(prometheusProperties);
}

@Bean
@ConditionalOnMissingBean
public io.micrometer.prometheus.PrometheusMeterRegistry prometheusMeterRegistry(
io.micrometer.prometheus.PrometheusConfig prometheusConfig, CollectorRegistry collectorRegistry,
Clock clock, ObjectProvider<ExemplarSampler> exemplarSamplerProvider) {
return new io.micrometer.prometheus.PrometheusMeterRegistry(prometheusConfig, collectorRegistry, clock,
exemplarSamplerProvider.getIfAvailable());
public PrometheusMeterRegistry prometheusMeterRegistry(PrometheusConfig prometheusConfig,
PrometheusRegistry prometheusRegistry, Clock clock) {
return new PrometheusMeterRegistry(prometheusConfig, prometheusRegistry, clock, null);
}

@Bean
@ConditionalOnMissingBean
public CollectorRegistry collectorRegistry() {
return new CollectorRegistry(true);
}

@Bean
@ConditionalOnMissingBean(ExemplarSampler.class)
@ConditionalOnBean(SpanContextSupplier.class)
public DefaultExemplarSampler exemplarSampler(SpanContextSupplier spanContextSupplier) {
return new DefaultExemplarSampler(spanContextSupplier);
public PrometheusRegistry prometheusRegistry() {
return new PrometheusRegistry();
}

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

@SuppressWarnings("removal")
@Bean
@ConditionalOnMissingBean
public PrometheusScrapeEndpoint prometheusEndpoint(CollectorRegistry collectorRegistry) {
return new PrometheusScrapeEndpoint(collectorRegistry);
}

}

/**
* Configuration for <a href="https://github.com/prometheus/pushgateway">Prometheus
* Pushgateway</a>.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(PushGateway.class)
@ConditionalOnProperty(prefix = "management.prometheus.metrics.export.pushgateway", name = "enabled")
public static class PrometheusPushGatewayConfiguration {

/**
* The fallback job name. We use 'spring' since there's a history of Prometheus
* spring integration defaulting to that name from when Prometheus integration
* didn't exist in Spring itself.
*/
private static final String FALLBACK_JOB = "spring";

@Bean
@ConditionalOnMissingBean
public PrometheusPushGatewayManager prometheusPushGatewayManager(CollectorRegistry collectorRegistry,
PrometheusProperties prometheusProperties, Environment environment) throws MalformedURLException {
PrometheusProperties.Pushgateway properties = prometheusProperties.getPushgateway();
Duration pushRate = properties.getPushRate();
String job = getJob(properties, environment);
Map<String, String> groupingKey = properties.getGroupingKey();
ShutdownOperation shutdownOperation = properties.getShutdownOperation();
PushGateway pushGateway = initializePushGateway(properties.getBaseUrl());
if (StringUtils.hasText(properties.getUsername())) {
pushGateway.setConnectionFactory(
new BasicAuthHttpConnectionFactory(properties.getUsername(), properties.getPassword()));
}
return new PrometheusPushGatewayManager(pushGateway, collectorRegistry, pushRate, job, groupingKey,
shutdownOperation);
}

private PushGateway initializePushGateway(String url) throws MalformedURLException {
return new PushGateway(new URL(url));
}

private String getJob(PrometheusProperties.Pushgateway properties, Environment environment) {
String job = properties.getJob();
job = (job != null) ? job : environment.getProperty("spring.application.name");
return (job != null) ? job : FALLBACK_JOB;
@ConditionalOnMissingBean(
value = { PrometheusScrapeEndpoint.class, PrometheusSimpleclientScrapeEndpoint.class })
public PrometheusScrapeEndpoint prometheusEndpoint(PrometheusRegistry prometheusRegistry) {
return new PrometheusScrapeEndpoint(prometheusRegistry);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
* @author Stephane Nicoll
* @since 2.0.0
*/
@SuppressWarnings("deprecation")
@ConfigurationProperties(prefix = "management.prometheus.metrics.export")
public class PrometheusProperties {

Expand All @@ -55,6 +54,8 @@ public class PrometheusProperties {
/**
* Histogram type for backing DistributionSummary and Timer.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated(since = "3.3.0", forRemoval = true)
private io.micrometer.prometheus.HistogramFlavor histogramFlavor = io.micrometer.prometheus.HistogramFlavor.Prometheus;

/**
Expand All @@ -70,10 +71,12 @@ public void setDescriptions(boolean descriptions) {
this.descriptions = descriptions;
}

@SuppressWarnings("deprecation")
public io.micrometer.prometheus.HistogramFlavor getHistogramFlavor() {
return this.histogramFlavor;
}

@SuppressWarnings("deprecation")
public void setHistogramFlavor(io.micrometer.prometheus.HistogramFlavor histogramFlavor) {
this.histogramFlavor = histogramFlavor;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@

import java.time.Duration;

import io.micrometer.prometheusmetrics.PrometheusConfig;

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

/**
* Adapter to convert {@link PrometheusProperties} to a
* {@link io.micrometer.prometheus.PrometheusConfig}.
* Adapter to convert {@link PrometheusProperties} to a {@link PrometheusConfig}.
*
* @author Jon Schneider
* @author Phillip Webb
*/
@SuppressWarnings("deprecation")
class PrometheusPropertiesConfigAdapter extends PropertiesConfigAdapter<PrometheusProperties>
implements io.micrometer.prometheus.PrometheusConfig {
implements PrometheusConfig {

PrometheusPropertiesConfigAdapter(PrometheusProperties properties) {
super(properties);
Expand All @@ -47,18 +47,12 @@ public String get(String key) {

@Override
public boolean descriptions() {
return get(PrometheusProperties::isDescriptions, io.micrometer.prometheus.PrometheusConfig.super::descriptions);
}

@Override
public io.micrometer.prometheus.HistogramFlavor histogramFlavor() {
return get(PrometheusProperties::getHistogramFlavor,
io.micrometer.prometheus.PrometheusConfig.super::histogramFlavor);
return get(PrometheusProperties::isDescriptions, PrometheusConfig.super::descriptions);
}

@Override
public Duration step() {
return get(PrometheusProperties::getStep, io.micrometer.prometheus.PrometheusConfig.super::step);
return get(PrometheusProperties::getStep, PrometheusConfig.super::step);
}

}
Loading

0 comments on commit 6d2f7b7

Please sign in to comment.