diff --git a/common/src/main/java/org/tron/common/prometheus/Metrics.java b/common/src/main/java/org/tron/common/prometheus/Metrics.java index 3f37cf331aa..40a57305b1a 100644 --- a/common/src/main/java/org/tron/common/prometheus/Metrics.java +++ b/common/src/main/java/org/tron/common/prometheus/Metrics.java @@ -1,11 +1,13 @@ package org.tron.common.prometheus; +import com.google.common.annotations.VisibleForTesting; import io.prometheus.client.Collector; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.Histogram; import io.prometheus.client.exporter.HTTPServer; import io.prometheus.client.hotspot.DefaultExports; import java.io.IOException; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.tron.common.parameter.CommonParameter; @@ -13,29 +15,26 @@ public class Metrics { public static final double MILLISECONDS_PER_SECOND = Collector.MILLISECONDS_PER_SECOND; + @Setter + @VisibleForTesting private static volatile boolean initialized = false; private Metrics() { throw new IllegalStateException("Metrics"); } - public static synchronized void init() { + public static synchronized void init() throws IOException { if(initialized) { return; } if (CommonParameter.getInstance().isMetricsPrometheusEnable()) { - try { - DefaultExports.initialize(); - new OperatingSystemExports().register(CollectorRegistry.defaultRegistry); - new GuavaCacheExports().register(CollectorRegistry.defaultRegistry); - int port = CommonParameter.getInstance().getMetricsPrometheusPort(); - new HTTPServer.Builder().withPort(port).build(); - logger.info("prometheus exposed on port : {}", port); - initialized = true; - } catch (IOException e) { - CommonParameter.getInstance().setMetricsPrometheusEnable(false); - logger.error("{}", e.getMessage()); - } + DefaultExports.initialize(); + new OperatingSystemExports().register(CollectorRegistry.defaultRegistry); + new GuavaCacheExports().register(CollectorRegistry.defaultRegistry); + int port = CommonParameter.getInstance().getMetricsPrometheusPort(); + new HTTPServer.Builder().withPort(port).build(); + logger.info("prometheus exposed on port : {}", port); + initialized = true; } } diff --git a/framework/src/main/java/org/tron/common/metrics/MetricService.java b/framework/src/main/java/org/tron/common/metrics/MetricService.java new file mode 100644 index 00000000000..6eccd89daca --- /dev/null +++ b/framework/src/main/java/org/tron/common/metrics/MetricService.java @@ -0,0 +1,14 @@ +package org.tron.common.metrics; + +import org.tron.common.prometheus.Metrics; + +public class MetricService { + + public static void startPrometheus() { + try { + Metrics.init(); + } catch (Exception e) { + throw new IllegalStateException("start Prometheus service failed.", e); + } + } +} diff --git a/framework/src/main/java/org/tron/program/FullNode.java b/framework/src/main/java/org/tron/program/FullNode.java index 699a0a8e61e..c5d6b339423 100644 --- a/framework/src/main/java/org/tron/program/FullNode.java +++ b/framework/src/main/java/org/tron/program/FullNode.java @@ -7,8 +7,8 @@ import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; import org.tron.common.log.LogResetter; +import org.tron.common.metrics.MetricService; import org.tron.common.parameter.CommonParameter; -import org.tron.common.prometheus.Metrics; import org.tron.core.Constant; import org.tron.core.config.DefaultConfig; import org.tron.core.config.args.Args; @@ -40,7 +40,7 @@ public static void main(String[] args) { } // init metrics first - Metrics.init(); + MetricService.startPrometheus(); DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); beanFactory.setAllowCircularReferences(false); diff --git a/framework/src/main/java/org/tron/program/SolidityNode.java b/framework/src/main/java/org/tron/program/SolidityNode.java index fd5f7d56ef5..30becafab73 100644 --- a/framework/src/main/java/org/tron/program/SolidityNode.java +++ b/framework/src/main/java/org/tron/program/SolidityNode.java @@ -11,8 +11,8 @@ import org.tron.common.application.ApplicationFactory; import org.tron.common.application.TronApplicationContext; import org.tron.common.client.DatabaseGrpcClient; +import org.tron.common.metrics.MetricService; import org.tron.common.parameter.CommonParameter; -import org.tron.common.prometheus.Metrics; import org.tron.core.ChainBaseManager; import org.tron.core.Constant; import org.tron.core.capsule.BlockCapsule; @@ -75,7 +75,7 @@ public static void main(String[] args) { return; } // init metrics first - Metrics.init(); + MetricService.startPrometheus(); Application appT = ApplicationFactory.create(context); SolidityNode node = new SolidityNode(appT.getDbManager()); diff --git a/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java b/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java index 98631210374..670c1911c2d 100644 --- a/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java +++ b/framework/src/test/java/org/tron/core/jsonrpc/JsonrpcServiceTest.java @@ -18,8 +18,8 @@ import org.junit.Before; import org.junit.Test; import org.tron.common.BaseTest; +import org.tron.common.metrics.MetricService; import org.tron.common.parameter.CommonParameter; -import org.tron.common.prometheus.Metrics; import org.tron.common.utils.ByteArray; import org.tron.common.utils.Sha256Hash; import org.tron.core.Constant; @@ -69,7 +69,7 @@ public class JsonrpcServiceTest extends BaseTest { CommonParameter.getInstance().setJsonRpcHttpPBFTNodeEnable(true); CommonParameter.getInstance().setJsonRpcHttpSolidityNodeEnable(true); CommonParameter.getInstance().setMetricsPrometheusEnable(true); - Metrics.init(); + MetricService.startPrometheus(); OWNER_ADDRESS = Wallet.getAddressPreFixString() + "abd4b9367799eaa3197fecb144eb71de1e049abc"; diff --git a/framework/src/test/java/org/tron/core/metrics/prometheus/PrometheusApiServiceTest.java b/framework/src/test/java/org/tron/core/metrics/prometheus/PrometheusApiServiceTest.java index 1c6e56cbbbe..7a3fb296a5e 100644 --- a/framework/src/test/java/org/tron/core/metrics/prometheus/PrometheusApiServiceTest.java +++ b/framework/src/test/java/org/tron/core/metrics/prometheus/PrometheusApiServiceTest.java @@ -15,9 +15,12 @@ import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.tron.common.BaseTest; import org.tron.common.crypto.ECKey; +import org.tron.common.metrics.MetricService; import org.tron.common.parameter.CommonParameter; import org.tron.common.prometheus.MetricLabels; import org.tron.common.prometheus.Metrics; @@ -54,11 +57,14 @@ public class PrometheusApiServiceTest extends BaseTest { @Resource private ChainBaseManager chainManager; + @Rule + public ExpectedException thrown = ExpectedException.none(); + static { Args.setParam(new String[] {"-d", dbPath(), "-w"}, Constant.TEST_CONF); Args.getInstance().setNodeListenPort(10000 + port.incrementAndGet()); initParameter(Args.getInstance()); - Metrics.init(); + MetricService.startPrometheus(); } protected static void initParameter(CommonParameter parameter) { @@ -134,6 +140,12 @@ public void testMetric() throws Exception { generateBlock(witnessAndAccount); } check(); + // try to start prometheus again + MetricService.startPrometheus(); + Metrics.setInitialized(false); + thrown.expect(IllegalStateException.class); + // try to start prometheus again + MetricService.startPrometheus(); } private Map addTestWitnessAndAccount() {