Polish "Add Prometheus push gateway support"

Rework Prometheus push gateway support so that the central class can
be used outside of auto-configuration. The shutdown flags have also
been replaced with a single "shutdown-operation" property since it's
unlikely that both "push" and "delete" will be required.

It's also possible now to supply a `TaskScheduler` to the manager.

See gh-14353
pull/14707/head
Phillip Webb 6 years ago
parent 4e71981f77
commit 20ecf73cd1

@ -16,25 +16,21 @@
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 java.time.Duration;
import java.util.Map;
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;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
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.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
@ -53,6 +49,7 @@ import org.springframework.core.env.Environment;
*
* @since 2.0.0
* @author Jon Schneider
* @author David J. M. Karlsen
*/
@Configuration
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
@ -100,108 +97,42 @@ 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 {
/**
* 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
public PushGatewayHandler pushGatewayHandler(CollectorRegistry collectorRegistry,
@ConditionalOnMissingBean
public PrometheusPushGatewayManager prometheusPushGatewayManager(
CollectorRegistry collectorRegistry,
PrometheusProperties prometheusProperties, Environment environment) {
return new PushGatewayHandler(collectorRegistry, prometheusProperties,
environment);
PrometheusProperties.Pushgateway properties = prometheusProperties
.getPushgateway();
PushGateway pushGateway = new PushGateway(properties.getBaseUrl());
Duration pushRate = properties.getPushRate();
String job = getJob(properties, environment);
Map<String, String> groupingKey = properties.getGroupingKey();
ShutdownOperation shutdownOperation = properties.getShutdownOperation();
return new PrometheusPushGatewayManager(pushGateway, collectorRegistry,
pushRate, job, groupingKey, shutdownOperation);
}
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;
}
private String getJob(PrometheusProperties.Pushgateway properties,
Environment environment) {
String job = properties.getJob();
job = (job != null) ? job
: environment.getProperty("spring.application.name");
job = (job != null) ? job : FALLBACK_JOB;
return job;
}
}

@ -20,6 +20,7 @@ import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager.ShutdownOperation;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
@ -42,7 +43,7 @@ public class PrometheusProperties {
* Configuration options for using Prometheus Pushgateway, allowing metrics to be
* pushed when they cannot be scraped.
*/
private PushgatewayProperties pushgateway = new PushgatewayProperties();
private Pushgateway pushgateway = new Pushgateway();
/**
* Step size (i.e. reporting frequency) to use.
@ -65,18 +66,18 @@ public class PrometheusProperties {
this.step = step;
}
public PushgatewayProperties getPushgateway() {
public Pushgateway getPushgateway() {
return this.pushgateway;
}
public void setPushgateway(PushgatewayProperties pushgateway) {
public void setPushgateway(Pushgateway pushgateway) {
this.pushgateway = pushgateway;
}
/**
* Configuration options for push-based interaction with Prometheus.
*/
public static class PushgatewayProperties {
public static class Pushgateway {
/**
* Enable publishing via a Prometheus Pushgateway.
@ -84,34 +85,29 @@ public class PrometheusProperties {
private Boolean enabled = false;
/**
* Required host:port or ip:port of the Pushgateway.
* Base URL for the Pushgateway.
*/
private String baseUrl = "localhost:9091";
/**
* Required identifier for this application instance.
*/
private String job;
/**
* Frequency with which to push metrics to Pushgateway.
* Frequency with which to push metrics.
*/
private Duration pushRate = Duration.ofMinutes(1);
/**
* Push metrics right before shut-down. Mostly useful for batch jobs.
* Job identifier for this application instance.
*/
private boolean pushOnShutdown = true;
private String job;
/**
* Delete metrics from Pushgateway when application is shut-down.
* Grouping key for the pushed metrics.
*/
private boolean deleteOnShutdown = true;
private Map<String, String> groupingKey = new HashMap<>();
/**
* Used to group metrics in pushgateway. A common example is setting
* Operation that should be performed on shutdown.
*/
private Map<String, String> groupingKeys = new HashMap<>();
private ShutdownOperation shutdownOperation = ShutdownOperation.NONE;
public Boolean getEnabled() {
return this.enabled;
@ -129,14 +125,6 @@ public class PrometheusProperties {
this.baseUrl = baseUrl;
}
public String getJob() {
return this.job;
}
public void setJob(String job) {
this.job = job;
}
public Duration getPushRate() {
return this.pushRate;
}
@ -145,28 +133,28 @@ public class PrometheusProperties {
this.pushRate = pushRate;
}
public boolean isPushOnShutdown() {
return this.pushOnShutdown;
public String getJob() {
return this.job;
}
public void setPushOnShutdown(boolean pushOnShutdown) {
this.pushOnShutdown = pushOnShutdown;
public void setJob(String job) {
this.job = job;
}
public boolean isDeleteOnShutdown() {
return this.deleteOnShutdown;
public Map<String, String> getGroupingKey() {
return this.groupingKey;
}
public void setDeleteOnShutdown(boolean deleteOnShutdown) {
this.deleteOnShutdown = deleteOnShutdown;
public void setGroupingKey(Map<String, String> groupingKey) {
this.groupingKey = groupingKey;
}
public Map<String, String> getGroupingKeys() {
return this.groupingKeys;
public ShutdownOperation getShutdownOperation() {
return this.shutdownOperation;
}
public void setGroupingKeys(Map<String, String> groupingKeys) {
this.groupingKeys = groupingKeys;
public void setShutdownOperation(ShutdownOperation shutdownOperation) {
this.shutdownOperation = shutdownOperation;
}
}

@ -22,8 +22,8 @@ import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.CollectorRegistry;
import org.junit.Test;
import org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus.PrometheusMetricsExportAutoConfiguration.PrometheusPushGatewayConfiguration;
import org.springframework.boot.actuate.autoconfigure.web.server.ManagementContextAutoConfiguration;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusScrapeEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@ -137,8 +137,8 @@ public class PrometheusMetricsExportAutoConfigurationTests {
.withPropertyValues(
"management.metrics.export.prometheus.pushgateway.enabled=true")
.withUserConfiguration(BaseConfiguration.class)
.run((context) -> assertThat(context).hasSingleBean(
PrometheusPushGatewayConfiguration.PushGatewayHandler.class));
.run((context) -> assertThat(context)
.hasSingleBean(PrometheusPushGatewayManager.class));
}
@Configuration

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@ -61,6 +62,11 @@
<artifactId>micrometer-registry-prometheus</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava-reactive-streams</artifactId>

@ -0,0 +1,201 @@
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.export.prometheus;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.PushGateway;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Class that can be used to managed the pushing of metrics to a {@link PushGateway
* Prometheus PushGateway}. Handles the scheduling of push operations, error handling and
* shutdown operations.
*
* @author David J. M. Karlsen
* @author Phillip Webb
* @since 2.1.0
*/
public class PrometheusPushGatewayManager {
private static final Logger logger = LoggerFactory
.getLogger(PrometheusPushGatewayManager.class);
private final PushGateway pushGateway;
private final CollectorRegistry registry;
private final String job;
private final Map<String, String> groupingKey;
private final ShutdownOperation shutdownOperation;
private final TaskScheduler scheduler;
private ScheduledFuture<?> scheduled;
/**
* Create a new {@link PrometheusPushGatewayManager} instance using a single threaded
* {@link TaskScheduler}.
* @param pushGateway the source push gateway
* @param registry the collector registry to push
* @param pushRate the rate at which push operations occur
* @param job the job ID for the operation
* @param groupingKeys an optional set of grouping keys for the operation
* @param shutdownOperation the shutdown operation that should be performed when
* context is closed.
*/
public PrometheusPushGatewayManager(PushGateway pushGateway,
CollectorRegistry registry, Duration pushRate, String job,
Map<String, String> groupingKeys, ShutdownOperation shutdownOperation) {
this(pushGateway, registry, new PushGatewayTaskScheduler(), pushRate, job,
groupingKeys, shutdownOperation);
}
/**
* Create a new {@link PrometheusPushGatewayManager} instance.
* @param pushGateway the source push gateway
* @param registry the collector registry to push
* @param scheduler the scheduler used for operations
* @param pushRate the rate at which push operations occur
* @param job the job ID for the operation
* @param groupingKey an optional set of grouping keys for the operation
* @param shutdownOperation the shutdown operation that should be performed when
* context is closed.
*/
public PrometheusPushGatewayManager(PushGateway pushGateway,
CollectorRegistry registry, TaskScheduler scheduler, Duration pushRate,
String job, Map<String, String> groupingKey,
ShutdownOperation shutdownOperation) {
Assert.notNull(pushGateway, "PushGateway must not be null");
Assert.notNull(registry, "Registry must not be null");
Assert.notNull(scheduler, "Scheduler must not be null");
Assert.notNull(pushRate, "PushRate must not be null");
Assert.hasLength(job, "Job must not be empty");
this.pushGateway = pushGateway;
this.registry = registry;
this.job = job;
this.groupingKey = groupingKey;
this.shutdownOperation = (shutdownOperation != null) ? shutdownOperation
: ShutdownOperation.NONE;
this.scheduler = scheduler;
this.scheduled = this.scheduler.scheduleAtFixedRate(this::push, pushRate);
}
private void push() {
try {
this.pushGateway.pushAdd(this.registry, this.job, this.groupingKey);
}
catch (UnknownHostException ex) {
String host = ex.getMessage();
String message = "Unable to locate prometheus push gateway host";
message += StringUtils.hasLength(host) ? " '" + host + "'" : "";
message += ". No longer attempting metrics publication to this host";
logger.error(message, ex);
shutdown(ShutdownOperation.NONE);
}
catch (Throwable ex) {
logger.error("Unable to push metrics to Prometheus Pushgateway", ex);
}
}
private void delete() {
try {
this.pushGateway.delete(this.job, this.groupingKey);
}
catch (Throwable ex) {
logger.error("Unable to delete metrics from Prometheus Pushgateway", ex);
}
}
/**
* Shutdown the manager, running any {@link ShutdownOperation}.
*/
public void shutdown() {
shutdown(this.shutdownOperation);
}
private void shutdown(ShutdownOperation shutdownOperation) {
if (this.scheduler instanceof PushGatewayTaskScheduler) {
((PushGatewayTaskScheduler) this.scheduler).shutdown();
}
this.scheduled.cancel(false);
switch (shutdownOperation) {
case PUSH:
push();
break;
case DELETE:
delete();
break;
}
}
/**
* The operation that should be performed on shutdown.
*/
public enum ShutdownOperation {
/**
* Don't perform any shutdown operation.
*/
NONE,
/**
* Perform a 'push' before shutdown.
*/
PUSH,
/**
* Perform a 'delete' before shutdown.
*/
DELETE
}
/**
* {@link TaskScheduler} used when the user doesn't specify one.
*/
static class PushGatewayTaskScheduler extends ThreadPoolTaskScheduler {
PushGatewayTaskScheduler() {
setPoolSize(1);
setDaemon(true);
setThreadGroupName("prometheus-push-gateway");
}
@Override
public ScheduledExecutorService getScheduledExecutor()
throws IllegalStateException {
return Executors.newSingleThreadScheduledExecutor(this::newThread);
}
}
}

@ -0,0 +1,215 @@
/*
* Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.actuate.metrics.export.prometheus;
import java.net.UnknownHostException;
import java.time.Duration;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.exporter.PushGateway;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager.PushGatewayTaskScheduler;
import org.springframework.boot.actuate.metrics.export.prometheus.PrometheusPushGatewayManager.ShutdownOperation;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Tests for {@link PrometheusPushGatewayManager}.
*
* @author Phillip Webb
*/
public class PrometheusPushGatewayManagerTests {
@Mock
private PushGateway pushGateway;
@Mock
private CollectorRegistry registry;
private TaskScheduler scheduler;
private Duration pushRate = Duration.ofSeconds(1);
private Map<String, String> groupingKey = Collections.singletonMap("foo", "bar");
@Captor
private ArgumentCaptor<Runnable> task;
@Mock
private ScheduledFuture<Object> future;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.scheduler = mockScheduler(TaskScheduler.class);
}
@Test
public void createWhenPushGatewayIsNullThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new PrometheusPushGatewayManager(null, this.registry,
this.scheduler, this.pushRate, "job", this.groupingKey, null))
.withMessage("PushGateway must not be null");
}
@Test
public void createWhenCollectorRegistryIsNullThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new PrometheusPushGatewayManager(this.pushGateway, null,
this.scheduler, this.pushRate, "job", this.groupingKey, null))
.withMessage("Registry must not be null");
}
@Test
public void createWhenSchedulerIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> new PrometheusPushGatewayManager(this.pushGateway, this.registry,
null, this.pushRate, "job", this.groupingKey, null))
.withMessage("Scheduler must not be null");
}
@Test
public void createWhenPushRateIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> new PrometheusPushGatewayManager(this.pushGateway, this.registry,
this.scheduler, null, "job", this.groupingKey, null))
.withMessage("PushRate must not be null");
}
@Test
public void createWhenJobIsEmptyThrowsException() {
assertThatIllegalArgumentException().isThrownBy(
() -> new PrometheusPushGatewayManager(this.pushGateway, this.registry,
this.scheduler, this.pushRate, "", this.groupingKey, null))
.withMessage("Job must not be empty");
}
@Test
public void createShouldSchedulePushAsFixedRate() throws Exception {
new PrometheusPushGatewayManager(this.pushGateway, this.registry, this.scheduler,
this.pushRate, "job", this.groupingKey, null);
verify(this.scheduler).scheduleAtFixedRate(this.task.capture(),
eq(this.pushRate));
this.task.getValue().run();
verify(this.pushGateway).pushAdd(this.registry, "job", this.groupingKey);
}
@Test
public void shutdownWhenOwnsSchedulerDoesShutdownScheduler() {
PushGatewayTaskScheduler ownedScheduler = mockScheduler(
PushGatewayTaskScheduler.class);
PrometheusPushGatewayManager manager = new PrometheusPushGatewayManager(
this.pushGateway, this.registry, ownedScheduler, this.pushRate, "job",
this.groupingKey, null);
manager.shutdown();
verify(ownedScheduler).shutdown();
}
@Test
public void shutdownWhenDoesNotOwnSchedulerDoesNotShutdownScheduler() {
ThreadPoolTaskScheduler otherScheduler = mockScheduler(
ThreadPoolTaskScheduler.class);
PrometheusPushGatewayManager manager = new PrometheusPushGatewayManager(
this.pushGateway, this.registry, otherScheduler, this.pushRate, "job",
this.groupingKey, null);
manager.shutdown();
verify(otherScheduler, never()).shutdown();
}
@Test
public void shutdownWhenShutdownOperationIsPushPerformsPushOnShutdown()
throws Exception {
PrometheusPushGatewayManager manager = new PrometheusPushGatewayManager(
this.pushGateway, this.registry, this.scheduler, this.pushRate, "job",
this.groupingKey, ShutdownOperation.PUSH);
manager.shutdown();
verify(this.future).cancel(false);
verify(this.pushGateway).pushAdd(this.registry, "job", this.groupingKey);
}
@Test
public void shutdownWhenShutdownOperationIsDeletePerformsDeleteOnShutdown()
throws Exception {
PrometheusPushGatewayManager manager = new PrometheusPushGatewayManager(
this.pushGateway, this.registry, this.scheduler, this.pushRate, "job",
this.groupingKey, ShutdownOperation.DELETE);
manager.shutdown();
verify(this.future).cancel(false);
verify(this.pushGateway).delete("job", this.groupingKey);
}
@Test
public void shutdownWhenShutdownOperationIsNoneDoesNothing() {
PrometheusPushGatewayManager manager = new PrometheusPushGatewayManager(
this.pushGateway, this.registry, this.scheduler, this.pushRate, "job",
this.groupingKey, ShutdownOperation.NONE);
manager.shutdown();
verify(this.future).cancel(false);
verifyZeroInteractions(this.pushGateway);
}
@Test
public void pushWhenUnknownHostExceptionIsThrownDoesShutdown() throws Exception {
new PrometheusPushGatewayManager(this.pushGateway, this.registry, this.scheduler,
this.pushRate, "job", this.groupingKey, null);
verify(this.scheduler).scheduleAtFixedRate(this.task.capture(),
eq(this.pushRate));
willThrow(new UnknownHostException("foo")).given(this.pushGateway)
.pushAdd(this.registry, "job", this.groupingKey);
this.task.getValue().run();
verify(this.future).cancel(false);
}
@Test
public void pushDoesNotThrowException() throws Exception {
new PrometheusPushGatewayManager(this.pushGateway, this.registry, this.scheduler,
this.pushRate, "job", this.groupingKey, null);
verify(this.scheduler).scheduleAtFixedRate(this.task.capture(),
eq(this.pushRate));
willThrow(RuntimeException.class).given(this.pushGateway).pushAdd(this.registry,
"job", this.groupingKey);
this.task.getValue().run();
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private <T extends TaskScheduler> T mockScheduler(Class<T> type) {
T scheduler = mock(type);
given(scheduler.scheduleAtFixedRate(isA(Runnable.class), isA(Duration.class)))
.willReturn((ScheduledFuture) this.future);
return scheduler;
}
}

@ -143,7 +143,6 @@
<nio-multipart-parser.version>1.1.0</nio-multipart-parser.version>
<pooled-jms-version>1.0.3</pooled-jms-version>
<postgresql.version>42.2.5</postgresql.version>
<!-- need to take care that this version harmonizes with micrometer ones -->
<prometheus-pushgateway.version>0.5.0</prometheus-pushgateway.version>
<quartz.version>2.3.0</quartz.version>
<querydsl.version>4.2.1</querydsl.version>

@ -1480,6 +1480,12 @@ content into your application. Rather, pick only the properties that you need.
management.metrics.export.prometheus.descriptions=true # Whether to enable publishing descriptions as part of the scrape payload to Prometheus. Turn this off to minimize the amount of data sent on each scrape.
management.metrics.export.prometheus.enabled=true # Whether exporting of metrics to Prometheus is enabled.
management.metrics.export.prometheus.step=1m # Step size (i.e. reporting frequency) to use.
management.metrics.export.prometheus.pushgateway.base-url=localhost:9091 # Base URL for the Pushgateway.
management.metrics.export.prometheus.pushgateway.enabled=false # Enable publishing via a Prometheus Pushgateway.
management.metrics.export.prometheus.pushgateway.grouping-key= # Grouping key for the pushed metrics.
management.metrics.export.prometheus.pushgateway.job= # Job identifier for this application instance.
management.metrics.export.prometheus.pushgateway.push-rate=1m # Frequency with which to push metrics.
management.metrics.export.prometheus.pushgateway.shutdown-operation= # Operation that should be performed on shutdown (none, push, delete).
management.metrics.export.signalfx.access-token= # SignalFX access token.
management.metrics.export.signalfx.batch-size=10000 # Number of measurements per request to use for this backend. If more measurements are found, then multiple requests will be made.
management.metrics.export.signalfx.connect-timeout=1s # Connection timeout for requests to this backend.

Loading…
Cancel
Save