Commit f4cc3ade authored by Phillip Webb's avatar Phillip Webb

Merge pull request #14353 from davidkarlsen

* pr/14353:
  Polish "Add Prometheus push gateway support"
  Add Prometheus push gateway support
parents 35752a54 20ecf73c
......@@ -147,6 +147,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.micrometer</groupId>
<artifactId>micrometer-registry-signalfx</artifactId>
......
......@@ -16,15 +16,21 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus;
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.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;
......@@ -36,12 +42,14 @@ 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.
*
* @since 2.0.0
* @author Jon Schneider
* @author David J. M. Karlsen
*/
@Configuration
@AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class,
......@@ -86,4 +94,47 @@ public class PrometheusMetricsExportAutoConfiguration {
}
/**
* Configuration for <a href="https://github.com/prometheus/pushgateway">Prometheus
* Pushgateway</a>.
*/
@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
@ConditionalOnMissingBean
public PrometheusPushGatewayManager prometheusPushGatewayManager(
CollectorRegistry collectorRegistry,
PrometheusProperties prometheusProperties, Environment 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);
}
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;
}
}
}
......@@ -17,7 +17,10 @@
package org.springframework.boot.actuate.autoconfigure.metrics.export.prometheus;
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;
/**
......@@ -36,6 +39,12 @@ public class PrometheusProperties {
*/
private boolean descriptions = true;
/**
* Configuration options for using Prometheus Pushgateway, allowing metrics to be
* pushed when they cannot be scraped.
*/
private Pushgateway pushgateway = new Pushgateway();
/**
* Step size (i.e. reporting frequency) to use.
*/
......@@ -57,4 +66,97 @@ public class PrometheusProperties {
this.step = step;
}
public Pushgateway getPushgateway() {
return this.pushgateway;
}
public void setPushgateway(Pushgateway pushgateway) {
this.pushgateway = pushgateway;
}
/**
* Configuration options for push-based interaction with Prometheus.
*/
public static class Pushgateway {
/**
* Enable publishing via a Prometheus Pushgateway.
*/
private Boolean enabled = false;
/**
* Base URL for the Pushgateway.
*/
private String baseUrl = "localhost:9091";
/**
* Frequency with which to push metrics.
*/
private Duration pushRate = Duration.ofMinutes(1);
/**
* Job identifier for this application instance.
*/
private String job;
/**
* Grouping key for the pushed metrics.
*/
private Map<String, String> groupingKey = new HashMap<>();
/**
* Operation that should be performed on shutdown.
*/
private ShutdownOperation shutdownOperation = ShutdownOperation.NONE;
public Boolean getEnabled() {
return this.enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public String getBaseUrl() {
return this.baseUrl;
}
public void setBaseUrl(String baseUrl) {
this.baseUrl = baseUrl;
}
public Duration getPushRate() {
return this.pushRate;
}
public void setPushRate(Duration pushRate) {
this.pushRate = pushRate;
}
public String getJob() {
return this.job;
}
public void setJob(String job) {
this.job = job;
}
public Map<String, String> getGroupingKey() {
return this.groupingKey;
}
public void setGroupingKey(Map<String, String> groupingKey) {
this.groupingKey = groupingKey;
}
public ShutdownOperation getShutdownOperation() {
return this.shutdownOperation;
}
public void setShutdownOperation(ShutdownOperation shutdownOperation) {
this.shutdownOperation = shutdownOperation;
}
}
}
......@@ -23,6 +23,7 @@ import io.prometheus.client.CollectorRegistry;
import org.junit.Test;
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;
......@@ -128,6 +129,18 @@ public class PrometheusMetricsExportAutoConfigurationTests {
.hasSingleBean(PrometheusScrapeEndpoint.class));
}
@Test
public void withPushGatewayEnabled() {
this.contextRunner
.withConfiguration(
AutoConfigurations.of(ManagementContextAutoConfiguration.class))
.withPropertyValues(
"management.metrics.export.prometheus.pushgateway.enabled=true")
.withUserConfiguration(BaseConfiguration.class)
.run((context) -> assertThat(context)
.hasSingleBean(PrometheusPushGatewayManager.class));
}
@Configuration
static class BaseConfiguration {
......
<?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>
......
/*
* 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);
}
}
}
/*
* 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,6 +143,7 @@
<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>
<prometheus-pushgateway.version>0.5.0</prometheus-pushgateway.version>
<quartz.version>2.3.0</quartz.version>
<querydsl.version>4.2.1</querydsl.version>
<rabbit-amqp-client.version>5.4.1</rabbit-amqp-client.version>
......@@ -989,6 +990,11 @@
<artifactId>netty-tcnative-boringssl-static</artifactId>
<version>${netty-tcnative.version}</version>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient_pushgateway</artifactId>
<version>${prometheus-pushgateway.version}</version>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-bom</artifactId>
......
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment