|
16 | 16 |
|
17 | 17 | package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus;
|
18 | 18 |
|
19 |
| -import java.net.UnknownHostException; |
20 |
| -import java.util.concurrent.Executors; |
21 |
| -import java.util.concurrent.ScheduledExecutorService; |
22 |
| -import java.util.concurrent.TimeUnit; |
23 |
| - |
24 |
| -import javax.annotation.PreDestroy; |
| 19 | +import java.time.Duration; |
| 20 | +import java.util.Map; |
25 | 21 |
|
26 | 22 | import io.micrometer.core.instrument.Clock;
|
27 | 23 | import io.micrometer.prometheus.PrometheusConfig;
|
28 | 24 | import io.micrometer.prometheus.PrometheusMeterRegistry;
|
29 | 25 | import io.prometheus.client.CollectorRegistry;
|
30 | 26 | import io.prometheus.client.exporter.PushGateway;
|
31 |
| -import org.slf4j.Logger; |
32 |
| -import org.slf4j.LoggerFactory; |
33 | 27 |
|
34 | 28 | import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
|
35 | 29 | import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
|
36 | 30 | import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
|
37 | 31 | import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
|
| 32 | +import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager; |
| 33 | +import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager.ShutdownOperation; |
38 | 34 | import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint;
|
39 | 35 | import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
40 | 36 | import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
|
53 | 49 | *
|
54 | 50 | * @since 2.0.0
|
55 | 51 | * @author Jon Schneider
|
| 52 | + * @author David J. M. Karlsen |
56 | 53 | */
|
57 | 54 | @Configuration
|
58 | 55 | @AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
|
@@ -100,108 +97,42 @@ public PrometheusScrapeEndpoint prometheusEndpoint(
|
100 | 97 | /**
|
101 | 98 | * Configuration for <a href="https://github.com/prometheus/pushgateway">Prometheus
|
102 | 99 | * Pushgateway</a>.
|
103 |
| - * |
104 |
| - * @author David J. M. Karlsen |
105 | 100 | */
|
106 | 101 | @Configuration
|
107 | 102 | @ConditionalOnClass(PushGateway.class)
|
108 | 103 | @ConditionalOnProperty(prefix = "management.metrics.export.prometheus.pushgateway", name = "enabled")
|
109 | 104 | public static class PrometheusPushGatewayConfiguration {
|
110 | 105 |
|
| 106 | + /** |
| 107 | + * The fallback job name. We use 'spring' since there's a history of Prometheus |
| 108 | + * spring integration defaulting to that name from when Prometheus integration |
| 109 | + * didn't exist in Spring itself. |
| 110 | + */ |
| 111 | + private static final String FALLBACK_JOB = "spring"; |
| 112 | + |
111 | 113 | @Bean
|
112 |
| - public PushGatewayHandler pushGatewayHandler(CollectorRegistry collectorRegistry, |
| 114 | + @ConditionalOnMissingBean |
| 115 | + public PrometheusPushGatewayManager prometheusPushGatewayManager( |
| 116 | + CollectorRegistry collectorRegistry, |
113 | 117 | PrometheusProperties prometheusProperties, Environment environment) {
|
114 |
| - return new PushGatewayHandler(collectorRegistry, prometheusProperties, |
115 |
| - environment); |
| 118 | + PrometheusProperties.Pushgateway properties = prometheusProperties |
| 119 | + .getPushgateway(); |
| 120 | + PushGateway pushGateway = new PushGateway(properties.getBaseUrl()); |
| 121 | + Duration pushRate = properties.getPushRate(); |
| 122 | + String job = getJob(properties, environment); |
| 123 | + Map<String, String> groupingKey = properties.getGroupingKey(); |
| 124 | + ShutdownOperation shutdownOperation = properties.getShutdownOperation(); |
| 125 | + return new PrometheusPushGatewayManager(pushGateway, collectorRegistry, |
| 126 | + pushRate, job, groupingKey, shutdownOperation); |
116 | 127 | }
|
117 | 128 |
|
118 |
| - static class PushGatewayHandler { |
119 |
| - |
120 |
| - private final Logger logger = LoggerFactory |
121 |
| - .getLogger(PrometheusPushGatewayConfiguration.class); |
122 |
| - |
123 |
| - private final CollectorRegistry collectorRegistry; |
124 |
| - |
125 |
| - private final PrometheusProperties.PushgatewayProperties pushgatewayProperties; |
126 |
| - |
127 |
| - private final PushGateway pushGateway; |
128 |
| - |
129 |
| - private final Environment environment; |
130 |
| - |
131 |
| - private final ScheduledExecutorService executorService; |
132 |
| - |
133 |
| - PushGatewayHandler(CollectorRegistry collectorRegistry, |
134 |
| - PrometheusProperties prometheusProperties, Environment environment) { |
135 |
| - this.collectorRegistry = collectorRegistry; |
136 |
| - this.pushgatewayProperties = prometheusProperties.getPushgateway(); |
137 |
| - this.pushGateway = new PushGateway( |
138 |
| - this.pushgatewayProperties.getBaseUrl()); |
139 |
| - this.environment = environment; |
140 |
| - this.executorService = Executors.newSingleThreadScheduledExecutor((r) -> { |
141 |
| - Thread thread = new Thread(r); |
142 |
| - thread.setDaemon(true); |
143 |
| - thread.setName("micrometer-pushgateway"); |
144 |
| - return thread; |
145 |
| - }); |
146 |
| - this.executorService.scheduleAtFixedRate(this::push, 0, |
147 |
| - this.pushgatewayProperties.getPushRate().toMillis(), |
148 |
| - TimeUnit.MILLISECONDS); |
149 |
| - } |
150 |
| - |
151 |
| - void push() { |
152 |
| - try { |
153 |
| - this.pushGateway.pushAdd(this.collectorRegistry, getJobName(), |
154 |
| - this.pushgatewayProperties.getGroupingKeys()); |
155 |
| - } |
156 |
| - catch (UnknownHostException ex) { |
157 |
| - this.logger.error("Unable to locate host '" |
158 |
| - + this.pushgatewayProperties.getBaseUrl() |
159 |
| - + "'. No longer attempting metrics publication to this host"); |
160 |
| - this.executorService.shutdown(); |
161 |
| - } |
162 |
| - catch (Throwable throwable) { |
163 |
| - this.logger.error("Unable to push metrics to Prometheus Pushgateway", |
164 |
| - throwable); |
165 |
| - } |
166 |
| - } |
167 |
| - |
168 |
| - @PreDestroy |
169 |
| - void shutdown() { |
170 |
| - this.executorService.shutdown(); |
171 |
| - if (this.pushgatewayProperties.isPushOnShutdown()) { |
172 |
| - push(); |
173 |
| - } |
174 |
| - if (this.pushgatewayProperties.isDeleteOnShutdown()) { |
175 |
| - delete(); |
176 |
| - } |
177 |
| - } |
178 |
| - |
179 |
| - private void delete() { |
180 |
| - try { |
181 |
| - this.pushGateway.delete(getJobName(), |
182 |
| - this.pushgatewayProperties.getGroupingKeys()); |
183 |
| - } |
184 |
| - catch (Throwable throwable) { |
185 |
| - this.logger.error( |
186 |
| - "Unable to delete metrics from Prometheus Pushgateway", |
187 |
| - throwable); |
188 |
| - } |
189 |
| - } |
190 |
| - |
191 |
| - private String getJobName() { |
192 |
| - String job = this.pushgatewayProperties.getJob(); |
193 |
| - if (job == null) { |
194 |
| - job = this.environment.getProperty("spring.application.name"); |
195 |
| - } |
196 |
| - if (job == null) { |
197 |
| - // There's a history of Prometheus spring integration defaulting the |
198 |
| - // getJobName name to "spring" from when |
199 |
| - // Prometheus integration didn't exist in Spring itself. |
200 |
| - job = "spring"; |
201 |
| - } |
202 |
| - return job; |
203 |
| - } |
204 |
| - |
| 129 | + private String getJob(PrometheusProperties.Pushgateway properties, |
| 130 | + Environment environment) { |
| 131 | + String job = properties.getJob(); |
| 132 | + job = (job != null) ? job |
| 133 | + : environment.getProperty("spring.application.name"); |
| 134 | + job = (job != null) ? job : FALLBACK_JOB; |
| 135 | + return job; |
205 | 136 | }
|
206 | 137 |
|
207 | 138 | }
|
|
0 commit comments