[PIE-1846] Add an experimental flag for disabling timers (#1837)

Signed-off-by: Adrian Sutton <adrian.sutton@consensys.net>
pull/2/head
mbaxter 5 years ago committed by GitHub
parent 2fd934efc8
commit 41ece1de64
  1. 19
      metrics/core/src/main/java/tech/pegasys/pantheon/metrics/prometheus/MetricsConfiguration.java
  2. 10
      metrics/core/src/main/java/tech/pegasys/pantheon/metrics/prometheus/PrometheusMetricsSystem.java
  3. 15
      metrics/core/src/test/java/tech/pegasys/pantheon/metrics/prometheus/PrometheusMetricsSystemTest.java
  4. 30
      pantheon/src/main/java/tech/pegasys/pantheon/cli/PantheonCommand.java
  5. 53
      pantheon/src/main/java/tech/pegasys/pantheon/cli/options/MetricsCLIOptions.java
  6. 5
      pantheon/src/test/java/tech/pegasys/pantheon/cli/CommandTestAbstract.java
  7. 40
      pantheon/src/test/java/tech/pegasys/pantheon/cli/options/MetricsCLIOptionsTest.java

@ -31,6 +31,7 @@ public class MetricsConfiguration {
private static final String DEFAULT_METRICS_PUSH_HOST = "127.0.0.1"; private static final String DEFAULT_METRICS_PUSH_HOST = "127.0.0.1";
public static final int DEFAULT_METRICS_PUSH_PORT = 9001; public static final int DEFAULT_METRICS_PUSH_PORT = 9001;
public static final Boolean DEFAULT_TIMERS_ENABLED = true;
private final boolean enabled; private final boolean enabled;
private final int port; private final int port;
@ -42,6 +43,7 @@ public class MetricsConfiguration {
private final int pushInterval; private final int pushInterval;
private final String prometheusJob; private final String prometheusJob;
private final List<String> hostsWhitelist; private final List<String> hostsWhitelist;
private final boolean timersEnabled;
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
@ -57,7 +59,8 @@ public class MetricsConfiguration {
final String pushHost, final String pushHost,
final int pushInterval, final int pushInterval,
final String prometheusJob, final String prometheusJob,
final List<String> hostsWhitelist) { final List<String> hostsWhitelist,
final boolean timersEnabled) {
this.enabled = enabled; this.enabled = enabled;
this.port = port; this.port = port;
this.host = host; this.host = host;
@ -68,6 +71,7 @@ public class MetricsConfiguration {
this.pushInterval = pushInterval; this.pushInterval = pushInterval;
this.prometheusJob = prometheusJob; this.prometheusJob = prometheusJob;
this.hostsWhitelist = hostsWhitelist; this.hostsWhitelist = hostsWhitelist;
this.timersEnabled = timersEnabled;
} }
public boolean isEnabled() { public boolean isEnabled() {
@ -110,6 +114,10 @@ public class MetricsConfiguration {
return Collections.unmodifiableCollection(this.hostsWhitelist); return Collections.unmodifiableCollection(this.hostsWhitelist);
} }
public boolean isTimersEnabled() {
return timersEnabled;
}
@Override @Override
public String toString() { public String toString() {
return MoreObjects.toStringHelper(this) return MoreObjects.toStringHelper(this)
@ -173,6 +181,7 @@ public class MetricsConfiguration {
private int pushInterval = 15; private int pushInterval = 15;
private String prometheusJob = "pantheon-client"; private String prometheusJob = "pantheon-client";
private List<String> hostsWhitelist = Arrays.asList("localhost", "127.0.0.1"); private List<String> hostsWhitelist = Arrays.asList("localhost", "127.0.0.1");
private boolean timersEnabled = DEFAULT_TIMERS_ENABLED;
private Builder() {} private Builder() {}
@ -226,6 +235,11 @@ public class MetricsConfiguration {
return this; return this;
} }
public Builder timersEnabled(final boolean timersEnabled) {
this.timersEnabled = timersEnabled;
return this;
}
public MetricsConfiguration build() { public MetricsConfiguration build() {
return new MetricsConfiguration( return new MetricsConfiguration(
enabled, enabled,
@ -237,7 +251,8 @@ public class MetricsConfiguration {
pushHost, pushHost,
pushInterval, pushInterval,
prometheusJob, prometheusJob,
hostsWhitelist); hostsWhitelist,
timersEnabled);
} }
} }
} }

@ -58,9 +58,12 @@ public class PrometheusMetricsSystem implements MetricsSystem {
cachedTimers = new ConcurrentHashMap<>(); cachedTimers = new ConcurrentHashMap<>();
private final Set<MetricCategory> enabledCategories; private final Set<MetricCategory> enabledCategories;
private final boolean timersEnabled;
PrometheusMetricsSystem(final Set<MetricCategory> enabledCategories) { PrometheusMetricsSystem(
final Set<MetricCategory> enabledCategories, final boolean timersEnabled) {
this.enabledCategories = ImmutableSet.copyOf(enabledCategories); this.enabledCategories = ImmutableSet.copyOf(enabledCategories);
this.timersEnabled = timersEnabled;
} }
public static MetricsSystem init(final MetricsConfiguration metricsConfiguration) { public static MetricsSystem init(final MetricsConfiguration metricsConfiguration) {
@ -68,7 +71,8 @@ public class PrometheusMetricsSystem implements MetricsSystem {
return new NoOpMetricsSystem(); return new NoOpMetricsSystem();
} }
final PrometheusMetricsSystem metricsSystem = final PrometheusMetricsSystem metricsSystem =
new PrometheusMetricsSystem(metricsConfiguration.getMetricCategories()); new PrometheusMetricsSystem(
metricsConfiguration.getMetricCategories(), metricsConfiguration.isTimersEnabled());
if (metricsSystem.isCategoryEnabled(StandardMetricCategory.PROCESS)) { if (metricsSystem.isCategoryEnabled(StandardMetricCategory.PROCESS)) {
metricsSystem.collectors.put( metricsSystem.collectors.put(
StandardMetricCategory.PROCESS, StandardMetricCategory.PROCESS,
@ -117,7 +121,7 @@ public class PrometheusMetricsSystem implements MetricsSystem {
return cachedTimers.computeIfAbsent( return cachedTimers.computeIfAbsent(
metricName, metricName,
(k) -> { (k) -> {
if (isCategoryEnabled(category)) { if (timersEnabled && isCategoryEnabled(category)) {
final Summary summary = final Summary summary =
Summary.build(metricName, help) Summary.build(metricName, help)
.quantile(0.2, 0.02) .quantile(0.2, 0.02)

@ -45,7 +45,7 @@ public class PrometheusMetricsSystemTest {
.thenComparing((o1, o2) -> o1.getLabels().equals(o2.getLabels()) ? 0 : 1); .thenComparing((o1, o2) -> o1.getLabels().equals(o2.getLabels()) ? 0 : 1);
private final MetricsSystem metricsSystem = private final MetricsSystem metricsSystem =
new PrometheusMetricsSystem(DEFAULT_METRIC_CATEGORIES); new PrometheusMetricsSystem(DEFAULT_METRIC_CATEGORIES, true);
@Test @Test
public void shouldCreateObservationFromCounter() { public void shouldCreateObservationFromCounter() {
@ -155,6 +155,19 @@ public class PrometheusMetricsSystemTest {
new Observation(RPC, "request", null, asList("method", "count"))); new Observation(RPC, "request", null, asList("method", "count")));
} }
@Test
public void shouldNotCreateObservationsFromTimerWhenTimersDisabled() {
final MetricsSystem metricsSystem =
new PrometheusMetricsSystem(DEFAULT_METRIC_CATEGORIES, false);
final LabelledMetric<OperationTimer> timer =
metricsSystem.createLabelledTimer(RPC, "request", "Some help", "methodName");
//noinspection EmptyTryBlock
try (final TimingContext ignored = timer.labels("method").startTimer()) {}
assertThat(metricsSystem.streamObservations()).isEmpty();
}
@Test @Test
public void shouldCreateObservationFromGauge() { public void shouldCreateObservationFromGauge() {
metricsSystem.createGauge(JVM, "myValue", "Help", () -> 7d); metricsSystem.createGauge(JVM, "myValue", "Help", () -> 7d);

@ -41,6 +41,7 @@ import tech.pegasys.pantheon.cli.custom.JsonRPCWhitelistHostsProperty;
import tech.pegasys.pantheon.cli.custom.RpcAuthFileValidator; import tech.pegasys.pantheon.cli.custom.RpcAuthFileValidator;
import tech.pegasys.pantheon.cli.error.PantheonExceptionHandler; import tech.pegasys.pantheon.cli.error.PantheonExceptionHandler;
import tech.pegasys.pantheon.cli.options.EthProtocolOptions; import tech.pegasys.pantheon.cli.options.EthProtocolOptions;
import tech.pegasys.pantheon.cli.options.MetricsCLIOptions;
import tech.pegasys.pantheon.cli.options.NetworkingOptions; import tech.pegasys.pantheon.cli.options.NetworkingOptions;
import tech.pegasys.pantheon.cli.options.RocksDBOptions; import tech.pegasys.pantheon.cli.options.RocksDBOptions;
import tech.pegasys.pantheon.cli.options.SynchronizerOptions; import tech.pegasys.pantheon.cli.options.SynchronizerOptions;
@ -160,6 +161,7 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
final NetworkingOptions networkingOptions = NetworkingOptions.create(); final NetworkingOptions networkingOptions = NetworkingOptions.create();
final SynchronizerOptions synchronizerOptions = SynchronizerOptions.create(); final SynchronizerOptions synchronizerOptions = SynchronizerOptions.create();
final EthProtocolOptions ethProtocolOptions = EthProtocolOptions.create(); final EthProtocolOptions ethProtocolOptions = EthProtocolOptions.create();
final MetricsCLIOptions metricsCLIOptions = MetricsCLIOptions.create();
final RocksDBOptions rocksDBOptions = RocksDBOptions.create(); final RocksDBOptions rocksDBOptions = RocksDBOptions.create();
final TransactionPoolOptions transactionPoolOptions = TransactionPoolOptions.create(); final TransactionPoolOptions transactionPoolOptions = TransactionPoolOptions.create();
private final RunnerBuilder runnerBuilder; private final RunnerBuilder runnerBuilder;
@ -715,19 +717,18 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
private PantheonCommand handleUnstableOptions() { private PantheonCommand handleUnstableOptions() {
// Add unstable options // Add unstable options
UnstableOptionsSubCommand.createUnstableOptions( final ImmutableMap.Builder<String, Object> unstableOptionsBuild = ImmutableMap.builder();
commandLine, final ImmutableMap<String, Object> unstableOptions =
ImmutableMap.of( unstableOptionsBuild
"P2P Network", .put("Ethereum Wire Protocol", ethProtocolOptions)
networkingOptions, .put("Metrics", metricsCLIOptions)
"Synchronizer", .put("P2P Network", networkingOptions)
synchronizerOptions, .put("RocksDB", rocksDBOptions)
"RocksDB", .put("Synchronizer", synchronizerOptions)
rocksDBOptions, .put("TransactionPool", transactionPoolOptions)
"Ethereum Wire Protocol", .build();
ethProtocolOptions,
"TransactionPool", UnstableOptionsSubCommand.createUnstableOptions(commandLine, unstableOptions);
transactionPoolOptions));
return this; return this;
} }
@ -1006,7 +1007,8 @@ public class PantheonCommand implements DefaultCommandValues, Runnable {
"--metrics-push-interval", "--metrics-push-interval",
"--metrics-push-prometheus-job")); "--metrics-push-prometheus-job"));
return MetricsConfiguration.builder() return metricsCLIOptions
.toDomainObject()
.enabled(isMetricsEnabled) .enabled(isMetricsEnabled)
.host(metricsHost) .host(metricsHost)
.port(metricsPort) .port(metricsPort)

@ -0,0 +1,53 @@
/*
* Copyright 2019 ConsenSys AG.
*
* 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 tech.pegasys.pantheon.cli.options;
import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration;
import java.util.Arrays;
import java.util.List;
import picocli.CommandLine;
public class MetricsCLIOptions implements CLIOptions<MetricsConfiguration.Builder> {
private static final String TIMERS_ENABLED_FLAG = "--Xmetrics-timers-enabled";
@CommandLine.Option(
names = TIMERS_ENABLED_FLAG,
hidden = true,
defaultValue = "true",
description = "Whether to enable timer metrics (default: ${DEFAULT-VALUE}).")
private Boolean timersEnabled = MetricsConfiguration.DEFAULT_TIMERS_ENABLED;
private MetricsCLIOptions() {}
public static MetricsCLIOptions create() {
return new MetricsCLIOptions();
}
public static MetricsCLIOptions fromConfiguration(final MetricsConfiguration config) {
final MetricsCLIOptions metricsOptions = create();
metricsOptions.timersEnabled = config.isTimersEnabled();
return metricsOptions;
}
@Override
public MetricsConfiguration.Builder toDomainObject() {
return MetricsConfiguration.builder().timersEnabled(timersEnabled);
}
@Override
public List<String> getCLIOptions() {
return Arrays.asList(TIMERS_ENABLED_FLAG + "=" + timersEnabled.toString());
}
}

@ -25,6 +25,7 @@ import tech.pegasys.pantheon.Runner;
import tech.pegasys.pantheon.RunnerBuilder; import tech.pegasys.pantheon.RunnerBuilder;
import tech.pegasys.pantheon.cli.config.EthNetworkConfig; import tech.pegasys.pantheon.cli.config.EthNetworkConfig;
import tech.pegasys.pantheon.cli.options.EthProtocolOptions; import tech.pegasys.pantheon.cli.options.EthProtocolOptions;
import tech.pegasys.pantheon.cli.options.MetricsCLIOptions;
import tech.pegasys.pantheon.cli.options.NetworkingOptions; import tech.pegasys.pantheon.cli.options.NetworkingOptions;
import tech.pegasys.pantheon.cli.options.RocksDBOptions; import tech.pegasys.pantheon.cli.options.RocksDBOptions;
import tech.pegasys.pantheon.cli.options.SynchronizerOptions; import tech.pegasys.pantheon.cli.options.SynchronizerOptions;
@ -288,5 +289,9 @@ public abstract class CommandTestAbstract {
public TransactionPoolOptions getTransactionPoolOptions() { public TransactionPoolOptions getTransactionPoolOptions() {
return transactionPoolOptions; return transactionPoolOptions;
} }
public MetricsCLIOptions getMetricsCLIOptions() {
return metricsCLIOptions;
}
} }
} }

@ -0,0 +1,40 @@
/*
* Copyright 2019 ConsenSys AG.
*
* 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 tech.pegasys.pantheon.cli.options;
import tech.pegasys.pantheon.metrics.prometheus.MetricsConfiguration;
public class MetricsCLIOptionsTest
extends AbstractCLIOptionsTest<MetricsConfiguration.Builder, MetricsCLIOptions> {
@Override
MetricsConfiguration.Builder createDefaultDomainObject() {
return MetricsConfiguration.builder();
}
@Override
MetricsConfiguration.Builder createCustomizedDomainObject() {
return MetricsConfiguration.builder()
.timersEnabled(!MetricsConfiguration.DEFAULT_TIMERS_ENABLED);
}
@Override
MetricsCLIOptions optionsFromDomainObject(final MetricsConfiguration.Builder domainObject) {
return MetricsCLIOptions.fromConfiguration(domainObject.build());
}
@Override
MetricsCLIOptions getOptionsFromPantheonCommand(final TestPantheonCommand pantheonCommand) {
return pantheonCommand.getMetricsCLIOptions();
}
}
Loading…
Cancel
Save