@ -16,10 +16,20 @@
@@ -16,10 +16,20 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus ;
import java.net.UnknownHostException ;
import java.util.concurrent.Executors ;
import java.util.concurrent.ScheduledExecutorService ;
import java.util.concurrent.TimeUnit ;
import javax.annotation.PreDestroy ;
import io.micrometer.core.instrument.Clock ;
import io.micrometer.prometheus.PrometheusConfig ;
import io.micrometer.prometheus.PrometheusMeterRegistry ;
import io.prometheus.client.CollectorRegistry ;
import io.prometheus.client.exporter.PushGateway ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint ;
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration ;
@ -36,6 +46,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -36,6 +46,7 @@ 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 ;
/ * *
* { @link EnableAutoConfiguration Auto - configuration } for exporting metrics to Prometheus .
@ -86,4 +97,113 @@ public class PrometheusMetricsExportAutoConfiguration {
@@ -86,4 +97,113 @@ public class PrometheusMetricsExportAutoConfiguration {
}
/ * *
* Configuration for < a href = "https://github.com/prometheus/pushgateway" > Prometheus
* Pushgateway < / a > .
*
* @author David J . M . Karlsen
* /
@Configuration
@ConditionalOnClass ( PushGateway . class )
@ConditionalOnProperty ( prefix = "management.metrics.export.prometheus.pushgateway" , name = "enabled" )
public static class PrometheusPushGatewayConfiguration {
@Bean
public PushGatewayHandler pushGatewayHandler ( CollectorRegistry collectorRegistry ,
PrometheusProperties prometheusProperties , Environment environment ) {
return new PushGatewayHandler ( collectorRegistry , prometheusProperties ,
environment ) ;
}
static class PushGatewayHandler {
private final Logger logger = LoggerFactory
. getLogger ( PrometheusPushGatewayConfiguration . class ) ;
private final CollectorRegistry collectorRegistry ;
private final PrometheusProperties . PushgatewayProperties pushgatewayProperties ;
private final PushGateway pushGateway ;
private final Environment environment ;
private final ScheduledExecutorService executorService ;
PushGatewayHandler ( CollectorRegistry collectorRegistry ,
PrometheusProperties prometheusProperties , Environment environment ) {
this . collectorRegistry = collectorRegistry ;
this . pushgatewayProperties = prometheusProperties . getPushgateway ( ) ;
this . pushGateway = new PushGateway (
this . pushgatewayProperties . getBaseUrl ( ) ) ;
this . environment = environment ;
this . executorService = Executors . newSingleThreadScheduledExecutor ( ( r ) - > {
Thread thread = new Thread ( r ) ;
thread . setDaemon ( true ) ;
thread . setName ( "micrometer-pushgateway" ) ;
return thread ;
} ) ;
this . executorService . scheduleAtFixedRate ( this : : push , 0 ,
this . pushgatewayProperties . getPushRate ( ) . toMillis ( ) ,
TimeUnit . MILLISECONDS ) ;
}
void push ( ) {
try {
this . pushGateway . pushAdd ( this . collectorRegistry , getJobName ( ) ,
this . pushgatewayProperties . getGroupingKeys ( ) ) ;
}
catch ( UnknownHostException ex ) {
this . logger . error ( "Unable to locate host '"
+ this . pushgatewayProperties . getBaseUrl ( )
+ "'. No longer attempting metrics publication to this host" ) ;
this . executorService . shutdown ( ) ;
}
catch ( Throwable throwable ) {
this . logger . error ( "Unable to push metrics to Prometheus Pushgateway" ,
throwable ) ;
}
}
@PreDestroy
void shutdown ( ) {
this . executorService . shutdown ( ) ;
if ( this . pushgatewayProperties . isPushOnShutdown ( ) ) {
push ( ) ;
}
if ( this . pushgatewayProperties . isDeleteOnShutdown ( ) ) {
delete ( ) ;
}
}
private void delete ( ) {
try {
this . pushGateway . delete ( getJobName ( ) ,
this . pushgatewayProperties . getGroupingKeys ( ) ) ;
}
catch ( Throwable throwable ) {
this . logger . error (
"Unable to delete metrics from Prometheus Pushgateway" ,
throwable ) ;
}
}
private String getJobName ( ) {
String job = this . pushgatewayProperties . getJob ( ) ;
if ( job = = null ) {
job = this . environment . getProperty ( "spring.application.name" ) ;
}
if ( job = = null ) {
// There's a history of Prometheus spring integration defaulting the
// getJobName name to "spring" from when
// Prometheus integration didn't exist in Spring itself.
job = "spring" ;
}
return job ;
}
}
}
}