diff --git a/hmily-bom/pom.xml b/hmily-bom/pom.xml index 570464f8..5d0ed104 100644 --- a/hmily-bom/pom.xml +++ b/hmily-bom/pom.xml @@ -89,7 +89,8 @@ 1.0.0 3.4.0 3.2.0 - 0.6.0 + 0.10.0 + 0.15.0 3.6.0 0.4 1.8.9 @@ -185,6 +186,13 @@ ${prometheus-java-client.version} + + + io.prometheus.jmx + collector + ${prometheus-jmx.version} + + com.google.code.gson gson diff --git a/hmily-config/hmily-config-api/src/main/java/org/dromara/hmily/config/api/entity/HmilyMetricsConfig.java b/hmily-config/hmily-config-api/src/main/java/org/dromara/hmily/config/api/entity/HmilyMetricsConfig.java index 854cc6ae..ca8e2674 100644 --- a/hmily-config/hmily-config-api/src/main/java/org/dromara/hmily/config/api/entity/HmilyMetricsConfig.java +++ b/hmily-config/hmily-config-api/src/main/java/org/dromara/hmily/config/api/entity/HmilyMetricsConfig.java @@ -17,16 +17,13 @@ package org.dromara.hmily.config.api.entity; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.regex.Pattern; -import javax.management.ObjectName; import lombok.Data; import org.dromara.hmily.config.api.AbstractConfig; import org.dromara.hmily.config.api.constant.PrefixConstants; import org.dromara.hmily.spi.HmilySPI; +import java.util.Properties; + /** * Metrics config. * @@ -42,10 +39,6 @@ public final class HmilyMetricsConfig extends AbstractConfig { private Integer port = 9091; - private boolean async = true; - - private Integer threadCount = Runtime.getRuntime().availableProcessors() << 1; - private String jmxConfig; private Properties props; @@ -54,134 +47,5 @@ public final class HmilyMetricsConfig extends AbstractConfig { public String prefix() { return PrefixConstants.METRICS_PREFIX; } - - @Data - public static class HmilyJmxConfig { - - /** - * The Start delay seconds. - */ - private Integer startDelaySeconds = 0; - - /** - * The Jmx url. - */ - private String jmxUrl = ""; - - /** - * The Username. - */ - private String username = ""; - - /** - * The Password. - */ - private String password = ""; - - /** - * The Ssl. - */ - private boolean ssl; - - /** - * The Lowercase output name. - */ - private boolean lowercaseOutputName; - - /** - * The Lowercase output label names. - */ - private boolean lowercaseOutputLabelNames; - - /** - * The Whitelist object names. - */ - private List whitelistObjectNames = new ArrayList<>(); - - /** - * The Blacklist object names. - */ - private List blacklistObjectNames = new ArrayList<>(); - - /** - * The Rules. - */ - private List rules = new ArrayList<>(); - - /** - * The type Rule. - */ - @Data - public static class Rule { - - private Pattern pattern; - - /** - * The Name. - */ - private String name; - - /** - * The Value. - */ - private String value; - - /** - * The Value factor. - */ - private Double valueFactor = 1.0; - - /** - * The Help. - */ - private String help; - - /** - * The Attr name snake case. - */ - private boolean attrNameSnakeCase; - - /** - * The Type. - */ - private Type type = Type.UNTYPED; - - /** - * The Label names. - */ - private List labelNames = new ArrayList<>(); - - /** - * The Label values. - */ - private List labelValues = new ArrayList<>(); - } - - /** - * The enum Type. - */ - public enum Type { - /** - * Counter type. - */ - COUNTER, - /** - * Gauge type. - */ - GAUGE, - /** - * Summary type. - */ - SUMMARY, - /** - * Histogram type. - */ - HISTOGRAM, - /** - * Untyped type. - */ - UNTYPED, - } - } } diff --git a/hmily-core/src/main/java/org/dromara/hmily/core/bootstrap/HmilyBootstrap.java b/hmily-core/src/main/java/org/dromara/hmily/core/bootstrap/HmilyBootstrap.java index 48501f1d..e195f04e 100644 --- a/hmily-core/src/main/java/org/dromara/hmily/core/bootstrap/HmilyBootstrap.java +++ b/hmily-core/src/main/java/org/dromara/hmily/core/bootstrap/HmilyBootstrap.java @@ -17,7 +17,6 @@ package org.dromara.hmily.core.bootstrap; -import java.util.Objects; import org.dromara.hmily.common.exception.HmilyRuntimeException; import org.dromara.hmily.common.hook.HmilyShutdownHook; import org.dromara.hmily.common.utils.StringUtils; @@ -33,13 +32,15 @@ import org.dromara.hmily.core.provide.ObjectProvide; import org.dromara.hmily.core.provide.ReflectObject; import org.dromara.hmily.core.repository.HmilyRepositoryFacade; import org.dromara.hmily.core.schedule.HmilyTransactionSelfRecoveryScheduled; -import org.dromara.hmily.metrics.spi.MetricsInit; +import org.dromara.hmily.metrics.facade.MetricsTrackerFacade; import org.dromara.hmily.repository.spi.HmilyRepository; import org.dromara.hmily.serializer.spi.HmilySerializer; import org.dromara.hmily.spi.ExtensionLoaderFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Objects; + /** * The type Hmily bootstrap. * @@ -92,9 +93,9 @@ public final class HmilyBootstrap { private void initMetrics() { HmilyMetricsConfig metricsConfig = ConfigEnv.getInstance().getConfig(HmilyMetricsConfig.class); if (Objects.nonNull(metricsConfig) && StringUtils.isNoneBlank(metricsConfig.getMetricsName())) { - MetricsInit metricsInit = ExtensionLoaderFactory.load(MetricsInit.class); - metricsInit.init(metricsConfig); - registerAutoCloseable(metricsInit); + MetricsTrackerFacade facade = new MetricsTrackerFacade(); + facade.start(metricsConfig); + registerAutoCloseable(facade); } } diff --git a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsInitFacade.java b/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsInitFacade.java deleted file mode 100644 index 4213ed9a..00000000 --- a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsInitFacade.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.facade; - -import com.google.common.base.Preconditions; -import java.util.Optional; -import org.dromara.hmily.config.api.entity.HmilyMetricsConfig; -import org.dromara.hmily.metrics.facade.handler.MetricsTrackerHandler; -import org.dromara.hmily.metrics.spi.MetricsInit; -import org.dromara.hmily.metrics.spi.MetricsTrackerManager; -import org.dromara.hmily.spi.ExtensionLoaderFactory; -import org.dromara.hmily.spi.HmilySPI; - -/** - * The type Metrics init facade. - * - * @author xiaoyu - */ -@HmilySPI(value = "metricsInit") -public class MetricsInitFacade implements MetricsInit { - - private static volatile boolean enabled; - - private static MetricsTrackerManager metricsTrackerManager; - - /** - * Gets enabled. - * - * @return the enabled - */ - public static boolean getEnabled() { - return enabled; - } - - @Override - public void init(final HmilyMetricsConfig metricsConfig) { - if (!enabled) { - doInit(metricsConfig); - } - } - - @Override - public void close() { - if (!enabled) { - return; - } - if (null != metricsTrackerManager) { - metricsTrackerManager.stop(); - } - MetricsTrackerHandler.getInstance().close(); - enabled = false; - } - - private static void doInit(final HmilyMetricsConfig metricsConfig) { - Preconditions.checkNotNull(metricsConfig, "metrics configuration can not be null."); - metricsTrackerManager = ExtensionLoaderFactory.load(MetricsTrackerManager.class, metricsConfig.getMetricsName()); - Preconditions.checkNotNull(metricsTrackerManager, "Can not find metrics tracker manager with metrics name in metrics configuration."); - metricsTrackerManager.start(metricsConfig); - Integer threadCount = Optional.ofNullable(metricsConfig.getThreadCount()).orElse(Runtime.getRuntime().availableProcessors()); - MetricsTrackerHandler.getInstance().init(metricsConfig.isAsync(), threadCount, metricsTrackerManager); - enabled = true; - } -} diff --git a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsTrackerFacade.java b/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsTrackerFacade.java new file mode 100644 index 00000000..6c8f0042 --- /dev/null +++ b/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsTrackerFacade.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.dromara.hmily.metrics.facade; + +import com.google.common.base.Preconditions; +import lombok.extern.slf4j.Slf4j; +import org.dromara.hmily.config.api.entity.HmilyMetricsConfig; +import org.dromara.hmily.metrics.spi.MetricsBootService; +import org.dromara.hmily.metrics.spi.MetricsRegister; +import org.dromara.hmily.spi.ExtensionLoaderFactory; + +import java.util.concurrent.atomic.AtomicBoolean; + +/** + * Metrics tracker facade. + */ +@Slf4j +public final class MetricsTrackerFacade implements AutoCloseable { + + private MetricsBootService metricsBootService; + + private final AtomicBoolean isStarted = new AtomicBoolean(false); + + /** + * Init for metrics tracker manager. + * + * @param metricsConfig metrics config + */ + public void start(final HmilyMetricsConfig metricsConfig) { + if (this.isStarted.compareAndSet(false, true)) { + metricsBootService = ExtensionLoaderFactory.load(MetricsBootService.class, metricsConfig.getMetricsName()); + Preconditions.checkNotNull(metricsBootService, + "Can not find metrics tracker manager with metrics name : %s in metrics configuration.", metricsConfig.getMetricsName()); + metricsBootService.start(metricsConfig, ExtensionLoaderFactory.load(MetricsRegister.class, metricsConfig.getMetricsName())); + } else { + log.info("metrics tracker has started !"); + } + } + + @Override + public void close() { + this.isStarted.compareAndSet(true, false); + if (null != metricsBootService) { + metricsBootService.stop(); + } + } +} + diff --git a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsTrackerHandlerFacade.java b/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsTrackerHandlerFacade.java deleted file mode 100644 index 4583232b..00000000 --- a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/MetricsTrackerHandlerFacade.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.facade; - -import java.util.Optional; -import java.util.function.Supplier; -import lombok.extern.slf4j.Slf4j; -import org.dromara.hmily.metrics.api.HistogramMetricsTrackerDelegate; -import org.dromara.hmily.metrics.api.SummaryMetricsTrackerDelegate; -import org.dromara.hmily.metrics.facade.handler.MetricsTrackerHandler; -import org.dromara.hmily.metrics.spi.MetricsHandlerFacade; -import org.dromara.hmily.spi.HmilySPI; - -/** - * Metrics tracker facade. - * - * @author xiaoyu - */ -@Slf4j -@HmilySPI(value = "metricsTrackerHandlerFacade") -public final class MetricsTrackerHandlerFacade implements MetricsHandlerFacade { - - @Override - public void counterIncrement(final String metricsLabel, final String... labelValues) { - if (MetricsInitFacade.getEnabled()) { - MetricsTrackerHandler.getInstance().counterInc(metricsLabel, labelValues); - } - } - - @Override - public void gaugeIncrement(final String metricsLabel, final String... labelValues) { - if (MetricsInitFacade.getEnabled()) { - MetricsTrackerHandler.getInstance().gaugeInc(metricsLabel, labelValues); - } - } - - @Override - public void gaugeDecrement(final String metricsLabel, final String... labelValues) { - if (MetricsInitFacade.getEnabled()) { - MetricsTrackerHandler.getInstance().gaugeDec(metricsLabel, labelValues); - } - } - - @Override - public Supplier histogramStartTimer(final String metricsLabel, final String... labelValues) { - if (!MetricsInitFacade.getEnabled()) { - return () -> false; - } - Optional histogramMetricsTrackerDelegate = MetricsTrackerHandler.getInstance().histogramStartTimer(metricsLabel, labelValues); - return () -> { - histogramMetricsTrackerDelegate.ifPresent(this::histogramObserveDuration); - return true; - }; - } - - private void histogramObserveDuration(final HistogramMetricsTrackerDelegate delegate) { - if (MetricsInitFacade.getEnabled()) { - MetricsTrackerHandler.getInstance().histogramObserveDuration(delegate); - } - } - - @Override - public Supplier summaryStartTimer(final String metricsLabel, final String... labelValues) { - if (!MetricsInitFacade.getEnabled()) { - return () -> false; - } - Optional optionalSummaryMetricsTrackerDelegate = MetricsTrackerHandler.getInstance().summaryStartTimer(metricsLabel, labelValues); - return () -> { - optionalSummaryMetricsTrackerDelegate.ifPresent(this::summaryObserveDuration); - return true; - }; - } - - private void summaryObserveDuration(final SummaryMetricsTrackerDelegate delegate) { - if (MetricsInitFacade.getEnabled()) { - MetricsTrackerHandler.getInstance().summaryObserveDuration(delegate); - } - } -} - diff --git a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/executor/MetricsThreadPoolExecutor.java b/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/executor/MetricsThreadPoolExecutor.java deleted file mode 100644 index 990f7db0..00000000 --- a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/executor/MetricsThreadPoolExecutor.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.facade.executor; - -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.dromara.hmily.common.concurrent.HmilyThreadFactory; - -/** - * Metrics thread pool executor. - */ -@Slf4j -public final class MetricsThreadPoolExecutor extends ThreadPoolExecutor { - - @Getter - private final String name; - - /** - * Instantiates a new Metrics thread pool executor. - * - * @param threadCount core and max thread count - * @param queueSize queue size - */ - public MetricsThreadPoolExecutor(final int threadCount, final int queueSize) { - super(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(queueSize), - HmilyThreadFactory.create("metrics", true), buildRejectedExecutionHandler(queueSize)); - this.name = "metrics"; - } - - private static RejectedExecutionHandler buildRejectedExecutionHandler(final int size) { - return (r, executor) -> { - BlockingQueue queue = executor.getQueue(); - while (queue.size() >= size) { - if (executor.isShutdown()) { - throw new RejectedExecutionException("metrics thread pool executor closed"); - } - ((MetricsThreadPoolExecutor) executor).onRejected(); - } - if (!executor.isShutdown()) { - executor.execute(r); - } - }; - } - - private void onRejected() { - log.info("...thread:{}, Saturation occurs, actuator:{}", Thread.currentThread().getName(), name); - } -} - diff --git a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/handler/MetricsTrackerHandler.java b/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/handler/MetricsTrackerHandler.java deleted file mode 100644 index 227d50bb..00000000 --- a/hmily-metrics/hmily-metrics-facade/src/main/java/org/dromara/hmily/metrics/facade/handler/MetricsTrackerHandler.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.facade.handler; - -import java.util.Arrays; -import java.util.Optional; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.dromara.hmily.metrics.api.CounterMetricsTracker; -import org.dromara.hmily.metrics.api.GaugeMetricsTracker; -import org.dromara.hmily.metrics.api.HistogramMetricsTracker; -import org.dromara.hmily.metrics.api.HistogramMetricsTrackerDelegate; -import org.dromara.hmily.metrics.api.MetricsTracker; -import org.dromara.hmily.metrics.api.NoneHistogramMetricsTrackerDelegate; -import org.dromara.hmily.metrics.api.NoneSummaryMetricsTrackerDelegate; -import org.dromara.hmily.metrics.api.SummaryMetricsTracker; -import org.dromara.hmily.metrics.api.SummaryMetricsTrackerDelegate; -import org.dromara.hmily.metrics.enums.MetricsTypeEnum; -import org.dromara.hmily.metrics.facade.executor.MetricsThreadPoolExecutor; -import org.dromara.hmily.metrics.spi.MetricsTrackerManager; - -/** - * Metrics tracker handler. - */ -@Slf4j -public final class MetricsTrackerHandler { - - private static final int FUTURE_GET_TIME_OUT_MILLISECONDS = 500; - - private static final int QUEUE_SIZE = 5000; - - @Getter - private MetricsTrackerManager metricsTrackerManager; - - @Getter - private ExecutorService executorService; - - private volatile boolean async; - - /** - * Get metrics tracker handler of lazy load singleton. - * - * @return Metrics tracker handler - */ - public static MetricsTrackerHandler getInstance() { - return MetricsTrackerHandlerHolder.INSTANCE; - } - - /** - * Init for metrics tracker handler. - * - * @param async async - * @param threadCount thread count - * @param metricsTrackerManager metrics tracker manager - */ - public void init(final boolean async, final int threadCount, final MetricsTrackerManager metricsTrackerManager) { - this.async = async; - this.metricsTrackerManager = metricsTrackerManager; - if (async) { - executorService = new MetricsThreadPoolExecutor(threadCount, QUEUE_SIZE); - } - } - - /** - * Increment of counter metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - */ - public void counterInc(final String metricsLabel, final String... labelValues) { - if (async) { - executorService.execute(() -> handlerCounter(metricsLabel, labelValues)); - } else { - handlerCounter(metricsLabel, labelValues); - } - } - - /** - * Increment of gauge metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - */ - public void gaugeInc(final String metricsLabel, final String... labelValues) { - if (async) { - executorService.execute(() -> handlerGaugeInc(metricsLabel, labelValues)); - } else { - handlerGaugeInc(metricsLabel, labelValues); - } - } - - /** - * Decrement of gauge metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - */ - public void gaugeDec(final String metricsLabel, final String... labelValues) { - if (async) { - executorService.execute(() -> handlerGaugeDec(metricsLabel, labelValues)); - } else { - handlerGaugeDec(metricsLabel, labelValues); - } - } - - /** - * Start timer of histogram metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - * @return histogram metrics tracker delegate - */ - public Optional histogramStartTimer(final String metricsLabel, final String... labelValues) { - if (async) { - try { - return executorService.submit(() -> handlerHistogramStartTimer(metricsLabel, labelValues)).get(FUTURE_GET_TIME_OUT_MILLISECONDS, TimeUnit.MILLISECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - throw new IllegalStateException(String.format("Error while fetching histogram metric with metricsLabel= %s and labelValues=%s", metricsLabel, Arrays.toString(labelValues)), e); - } - } else { - return handlerHistogramStartTimer(metricsLabel, labelValues); - } - } - - /** - * Observe amount of time since start time with histogram metrics tracker. - * - * @param delegate histogram metrics tracker delegate - */ - public void histogramObserveDuration(final HistogramMetricsTrackerDelegate delegate) { - if (async) { - executorService.execute(delegate::observeDuration); - } else { - delegate.observeDuration(); - } - } - - /** - * Start timer of summary metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - * @return summary metrics tracker delegate - */ - public Optional summaryStartTimer(final String metricsLabel, final String... labelValues) { - if (async) { - try { - return executorService.submit(() -> handlerSummaryStartTimer(metricsLabel, labelValues)).get(FUTURE_GET_TIME_OUT_MILLISECONDS, TimeUnit.SECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException e) { - throw new IllegalStateException(String.format("Error while fetching summary metric with metricsLabel= %s and labelValues=%s", metricsLabel, Arrays.toString(labelValues)), e); - } - } else { - return handlerSummaryStartTimer(metricsLabel, labelValues); - } - } - - /** - * Observe amount of time since start time with summary metrics tracker. - * - * @param delegate summary metrics tracker delegate - */ - public void summaryObserveDuration(final SummaryMetricsTrackerDelegate delegate) { - if (async) { - executorService.execute(delegate::observeDuration); - } else { - delegate.observeDuration(); - } - } - - /** - * Executor service close. - */ - public void close() { - async = false; - if (null != executorService && !executorService.isShutdown()) { - executorService.shutdown(); - } - } - - private void handlerCounter(final String metricsLabel, final String... labelValues) { - metricsTrackerManager.getMetricsTrackerFactory().create(MetricsTypeEnum.COUNTER.name(), metricsLabel) - .ifPresent(metricsTracker -> ((CounterMetricsTracker) metricsTracker).inc(1.0, labelValues)); - } - - private void handlerGaugeInc(final String metricsLabel, final String... labelValues) { - metricsTrackerManager.getMetricsTrackerFactory().create(MetricsTypeEnum.GAUGE.name(), metricsLabel) - .ifPresent(metricsTracker -> ((GaugeMetricsTracker) metricsTracker).inc(1.0, labelValues)); - } - - /** - * Handler gauge dec. - * - * @param metricsLabel the metrics label - * @param labelValues the label values - */ - public void handlerGaugeDec(final String metricsLabel, final String... labelValues) { - metricsTrackerManager.getMetricsTrackerFactory().create(MetricsTypeEnum.GAUGE.name(), metricsLabel) - .ifPresent(metricsTracker -> ((GaugeMetricsTracker) metricsTracker).dec(1.0, labelValues)); - } - - private Optional handlerHistogramStartTimer(final String metricsLabel, final String... labelValues) { - Optional metricsTracker = metricsTrackerManager.getMetricsTrackerFactory().create(MetricsTypeEnum.HISTOGRAM.name(), metricsLabel); - return metricsTracker.map(tracker -> Optional.of(((HistogramMetricsTracker) tracker).startTimer(labelValues))).orElseGet(() -> Optional.of(new NoneHistogramMetricsTrackerDelegate())); - } - - private Optional handlerSummaryStartTimer(final String metricsLabel, final String... labelValues) { - Optional metricsTracker = metricsTrackerManager.getMetricsTrackerFactory().create(MetricsTypeEnum.SUMMARY.name(), metricsLabel); - return metricsTracker.map(tracker -> Optional.of(((SummaryMetricsTracker) tracker).startTimer(labelValues))).orElseGet(() -> Optional.of(new NoneSummaryMetricsTrackerDelegate())); - } - - /** - * Metrics tracker handler holder. - */ - private static class MetricsTrackerHandlerHolder { - - private static final MetricsTrackerHandler INSTANCE = new MetricsTrackerHandler(); - } -} - diff --git a/hmily-metrics/hmily-metrics-facade/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsHandlerFacade b/hmily-metrics/hmily-metrics-facade/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsHandlerFacade deleted file mode 100644 index 49a1ee85..00000000 --- a/hmily-metrics/hmily-metrics-facade/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsHandlerFacade +++ /dev/null @@ -1,18 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. -# - -org.dromara.hmily.metrics.facade.MetricsTrackerHandlerFacade diff --git a/hmily-metrics/hmily-metrics-facade/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsInit b/hmily-metrics/hmily-metrics-facade/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsInit deleted file mode 100644 index fd940d13..00000000 --- a/hmily-metrics/hmily-metrics-facade/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsInit +++ /dev/null @@ -1,18 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You 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. -# - -org.dromara.hmily.metrics.facade.MetricsInitFacade diff --git a/hmily-metrics/hmily-metrics-prometheus/pom.xml b/hmily-metrics/hmily-metrics-prometheus/pom.xml index 222ec563..3d8b93ca 100644 --- a/hmily-metrics/hmily-metrics-prometheus/pom.xml +++ b/hmily-metrics/hmily-metrics-prometheus/pom.xml @@ -56,5 +56,9 @@ io.prometheus simpleclient_hotspot + + io.prometheus.jmx + collector + \ No newline at end of file diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/PrometheusMetricsTrackerFactory.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/PrometheusMetricsTrackerFactory.java deleted file mode 100644 index 737ad599..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/PrometheusMetricsTrackerFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Optional; -import org.dromara.hmily.metrics.api.MetricsTracker; -import org.dromara.hmily.metrics.api.MetricsTrackerFactory; -import org.dromara.hmily.metrics.prometheus.impl.counter.TransactionStatusCounterMetricsTracker; -import org.dromara.hmily.metrics.prometheus.impl.counter.TransactionTotalCounterMetricsTracker; -import org.dromara.hmily.metrics.prometheus.impl.histogram.TransactionLatencyHistogramMetricsTracker; -import org.dromara.hmily.metrics.prometheus.impl.summary.TransactionLatencySummaryMetricsTracker; - -/** - * Prometheus metrics tracker factory. - * - * @author xiaoyu - */ -public final class PrometheusMetricsTrackerFactory implements MetricsTrackerFactory { - - private static final Collection REGISTER = new ArrayList<>(); - - static { - REGISTER.add(new TransactionTotalCounterMetricsTracker()); - REGISTER.add(new TransactionStatusCounterMetricsTracker()); - REGISTER.add(new TransactionLatencyHistogramMetricsTracker()); - REGISTER.add(new TransactionLatencySummaryMetricsTracker()); - } - - @Override - public Optional create(final String metricsType, final String metricsLabel) { - return REGISTER.stream().filter(each -> each.metricsLabel().equals(metricsLabel) && each.metricsType().equals(metricsType)).findFirst(); - } -} - diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/BuildInfoCollector.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/collector/BuildInfoCollector.java similarity index 95% rename from hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/BuildInfoCollector.java rename to hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/collector/BuildInfoCollector.java index 7d503458..9815e126 100644 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/BuildInfoCollector.java +++ b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/collector/BuildInfoCollector.java @@ -15,19 +15,17 @@ * limitations under the License. */ -package org.dromara.hmily.metrics.prometheus.impl.collector; +package org.dromara.hmily.metrics.prometheus.collector; import io.prometheus.client.Collector; import io.prometheus.client.GaugeMetricFamily; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; - /** * The type Build info collector. - * - * @author xiaoyu */ public class BuildInfoCollector extends Collector { diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxCollector.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxCollector.java deleted file mode 100644 index c4da6ca1..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxCollector.java +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.collector; - -import io.prometheus.client.Collector; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentSkipListMap; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.management.MalformedObjectNameException; -import javax.management.ObjectName; -import org.dromara.hmily.common.utils.GsonUtils; -import org.dromara.hmily.config.api.entity.HmilyMetricsConfig; - -/** - * The type Jmx collector. - * - * @author xiaoyu - */ -public class JmxCollector extends Collector implements Collector.Describable { - - private static final Logger LOGGER = Logger.getLogger(JmxCollector.class.getName()); - - private HmilyMetricsConfig.HmilyJmxConfig config; - - private long createTimeNanoSecs = System.nanoTime(); - - private final JmxMBeanPropertyCache jmxMBeanPropertyCache = new JmxMBeanPropertyCache(); - - /** - * Instantiates a new Jmx collector. - * - * @param json the json - * @throws MalformedObjectNameException the malformed object name exception - */ - public JmxCollector(final String json) throws MalformedObjectNameException { - config = loadConfig(GsonUtils.getInstance().toObjectMap(json)); - } - - private HmilyMetricsConfig.HmilyJmxConfig loadConfig(final Map paramMap) throws MalformedObjectNameException { - HmilyMetricsConfig.HmilyJmxConfig cfg = new HmilyMetricsConfig.HmilyJmxConfig(); - if (paramMap == null || paramMap.size() == 0) { - return cfg; - } - if (paramMap.containsKey("startDelaySeconds")) { - try { - cfg.setStartDelaySeconds((Integer) paramMap.get("startDelaySeconds")); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid number provided for startDelaySeconds", e); - } - } - if (paramMap.containsKey("hostPort")) { - if (paramMap.containsKey("jmxUrl")) { - throw new IllegalArgumentException("At most one of hostPort and jmxUrl must be provided"); - } - cfg.setJmxUrl("service:jmx:rmi:///jndi/rmi://" + paramMap.get("hostPort") + "/jmxrmi"); - } else if (paramMap.containsKey("jmxUrl")) { - cfg.setJmxUrl((String) paramMap.get("jmxUrl")); - } - - if (paramMap.containsKey("username")) { - cfg.setUsername((String) paramMap.get("username")); - } - - if (paramMap.containsKey("password")) { - cfg.setPassword((String) paramMap.get("password")); - } - - if (paramMap.containsKey("ssl")) { - cfg.setSsl((Boolean) paramMap.get("ssl")); - } - - if (paramMap.containsKey("lowercaseOutputName")) { - cfg.setLowercaseOutputName((Boolean) paramMap.get("lowercaseOutputName")); - } - - if (paramMap.containsKey("lowercaseOutputLabelNames")) { - cfg.setLowercaseOutputLabelNames((Boolean) paramMap.get("lowercaseOutputLabelNames")); - } - - if (paramMap.containsKey("whitelistObjectNames")) { - List names = GsonUtils.getInstance().fromList(paramMap.get("whitelistObjectNames").toString(), String.class); - for (String name : names) { - cfg.getWhitelistObjectNames().add(new ObjectName(name)); - } - } - - if (paramMap.containsKey("blacklistObjectNames")) { - List names = GsonUtils.getInstance().fromList(paramMap.get("blacklistObjectNames").toString(), String.class); - for (String name : names) { - cfg.getBlacklistObjectNames().add(new ObjectName(name)); - } - } - - if (paramMap.containsKey("rules")) { - List> configRules = GsonUtils.getInstance().toListMap(paramMap.get("rules").toString()); - for (Map ruleObject : configRules) { - HmilyMetricsConfig.HmilyJmxConfig.Rule rule = new HmilyMetricsConfig.HmilyJmxConfig.Rule(); - cfg.getRules().add(rule); - if (ruleObject.containsKey("pattern")) { - rule.setPattern(Pattern.compile("^.*(?:" + ruleObject.get("pattern") + ").*$")); - } - if (ruleObject.containsKey("name")) { - rule.setName((String) ruleObject.get("name")); - } - if (ruleObject.containsKey("value")) { - rule.setValue(String.valueOf(ruleObject.get("value"))); - } - if (ruleObject.containsKey("valueFactor")) { - String valueFactor = String.valueOf(ruleObject.get("valueFactor")); - try { - rule.setValueFactor(Double.valueOf(valueFactor)); - } catch (NumberFormatException e) { - // use default value - } - } - if (ruleObject.containsKey("attrNameSnakeCase")) { - rule.setAttrNameSnakeCase((Boolean) ruleObject.get("attrNameSnakeCase")); - } - if (ruleObject.containsKey("type")) { - rule.setType(HmilyMetricsConfig.HmilyJmxConfig.Type.valueOf(String.valueOf(ruleObject.containsKey("type")))); - } - if (ruleObject.containsKey("help")) { - rule.setHelp(String.valueOf(ruleObject.get("help"))); - } - if (ruleObject.containsKey("labels")) { - ConcurrentSkipListMap labels = GsonUtils.getInstance().toTreeMap(ruleObject.get("labels").toString()); - for (Map.Entry entry : labels.entrySet()) { - rule.getLabelNames().add(entry.getKey()); - rule.getLabelValues().add((String) entry.getValue()); - } - } - // Validation. - if ((rule.getLabelValues() != null || rule.getHelp() != null) && rule.getName() == null) { - throw new IllegalArgumentException("Must provide name, if help or labels are given: " + ruleObject); - } - if (rule.getName() != null && rule.getPattern() == null) { - throw new IllegalArgumentException("Must provide pattern, if name is given: " + ruleObject); - } - } - } else { - // Default to a single default rule. - cfg.getRules().add(new HmilyMetricsConfig.HmilyJmxConfig.Rule()); - } - return cfg; - } - - private static String toSnakeAndLowerCase(final String attrName) { - if (attrName == null || attrName.isEmpty()) { - return attrName; - } - char firstChar = attrName.subSequence(0, 1).charAt(0); - boolean prevCharIsUpperCaseOrUnderscore = Character.isUpperCase(firstChar) || firstChar == '_'; - StringBuilder resultBuilder = new StringBuilder(attrName.length()).append(Character.toLowerCase(firstChar)); - for (char attrChar : attrName.substring(1).toCharArray()) { - boolean charIsUpperCase = Character.isUpperCase(attrChar); - if (!prevCharIsUpperCaseOrUnderscore && charIsUpperCase) { - resultBuilder.append("_"); - } - resultBuilder.append(Character.toLowerCase(attrChar)); - prevCharIsUpperCaseOrUnderscore = charIsUpperCase || attrChar == '_'; - } - return resultBuilder.toString(); - } - - private static String safeName(final String name) { - if (name == null) { - return null; - } - boolean prevCharIsUnderscore = false; - StringBuilder safeNameBuilder = new StringBuilder(name.length()); - if (!name.isEmpty() && Character.isDigit(name.charAt(0))) { - // prevent a numeric prefix. - safeNameBuilder.append("_"); - } - for (char nameChar : name.toCharArray()) { - boolean isUnsafeChar = !JmxCollector.isLegalCharacter(nameChar); - if (isUnsafeChar || nameChar == '_') { - if (!prevCharIsUnderscore) { - safeNameBuilder.append("_"); - prevCharIsUnderscore = true; - } - } else { - safeNameBuilder.append(nameChar); - prevCharIsUnderscore = false; - } - } - return safeNameBuilder.toString(); - } - - private static boolean isLegalCharacter(final char input) { - return (input == ':') || (input == '_') || (input >= 'a' && input <= 'z') || (input >= 'A' && input <= 'Z') || (input >= '0' && input <= '9'); - } - - @Override - public List collect() { - Receiver receiver = new Receiver(); - JmxScraper scraper = new JmxScraper(config.getJmxUrl(), config.getUsername(), config.getPassword(), config.isSsl(), - config.getWhitelistObjectNames(), config.getBlacklistObjectNames(), receiver, jmxMBeanPropertyCache); - long start = System.nanoTime(); - double error = 0; - if ((config.getStartDelaySeconds() > 0) && ((start - createTimeNanoSecs) / 1000000000L < config.getStartDelaySeconds())) { - throw new IllegalStateException("JMXCollector waiting for startDelaySeconds"); - } - try { - scraper.doScrape(); - } catch (IOException e) { - error = 1; - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - LOGGER.severe("JMX scrape failed: " + sw.toString()); - } - List mfsList = new ArrayList<>(receiver.metricFamilySamplesMap.values()); - List samples = new ArrayList<>(); - samples.add(new MetricFamilySamples.Sample( - "jmx_scrape_duration_seconds", new ArrayList<>(), new ArrayList<>(), (System.nanoTime() - start) / 1.0E9)); - mfsList.add(new MetricFamilySamples("jmx_scrape_duration_seconds", Type.GAUGE, "Time this JMX scrape took, in seconds.", samples)); - samples = new ArrayList<>(); - samples.add(new MetricFamilySamples.Sample( - "jmx_scrape_error", new ArrayList<>(), new ArrayList<>(), error)); - mfsList.add(new MetricFamilySamples("jmx_scrape_error", Type.GAUGE, "Non-zero if this scrape failed.", samples)); - return mfsList; - } - - @Override - public List describe() { - List sampleFamilies = new ArrayList<>(); - sampleFamilies.add(new MetricFamilySamples("jmx_scrape_duration_seconds", Type.GAUGE, "Time this JMX scrape took, in seconds.", new ArrayList<>())); - sampleFamilies.add(new MetricFamilySamples("jmx_scrape_error", Type.GAUGE, "Non-zero if this scrape failed.", new ArrayList<>())); - return sampleFamilies; - } - - /** - * The type Receiver. - */ - class Receiver implements MBeanReceiver { - - private static final char SEP = '_'; - - private Map metricFamilySamplesMap = new HashMap<>(); - - // [] and () are special in regexes, so swtich to <>. - private String angleBrackets(final String s) { - return "<" + s.substring(1, s.length() - 1) + ">"; - } - - /** - * Add sample. - * - * @param sample the sample - * @param type the type - * @param help the help - */ - void addSample(final MetricFamilySamples.Sample sample, final Type type, final String help) { - MetricFamilySamples mfs = metricFamilySamplesMap.get(sample.name); - if (mfs == null) { - // JmxScraper.MBeanReceiver is only called from one thread, - // so there's no race here. - mfs = new MetricFamilySamples(sample.name, type, help, new ArrayList<>()); - metricFamilySamplesMap.put(sample.name, mfs); - } - mfs.samples.add(sample); - } - - private void defaultExport(final String domain, final Map beanProperties, - final LinkedList attrKeys, final String attrName, final String help, final Object value, final Type type) { - StringBuilder name = new StringBuilder(); - name.append(domain); - if (beanProperties.size() > 0) { - name.append(SEP); - name.append(beanProperties.values().iterator().next()); - } - for (String k : attrKeys) { - name.append(SEP); - name.append(k); - } - name.append(SEP); - name.append(attrName); - String fullname = safeName(name.toString()); - - if (config.isLowercaseOutputName()) { - fullname = fullname.toLowerCase(); - } - - List labelNames = new ArrayList<>(); - List labelValues = new ArrayList<>(); - if (beanProperties.size() > 1) { - Iterator> iter = beanProperties.entrySet().iterator(); - // Skip the first one, it's been used in the name. - iter.next(); - while (iter.hasNext()) { - Map.Entry entry = iter.next(); - String labelName = safeName(entry.getKey()); - if (config.isLowercaseOutputName()) { - labelName = labelName.toLowerCase(); - } - labelNames.add(labelName); - labelValues.add(entry.getValue()); - } - } - addSample(new MetricFamilySamples.Sample(fullname, labelNames, labelValues, ((Number) value).doubleValue()), type, help); - } - - public void recordBean(final String domain, final Map beanProperties, final LinkedList attrKeys, - final String attrName, final String attrType, final String attrDescription, final Object beanObject) { - String beanName = domain + angleBrackets(beanProperties.toString()) + angleBrackets(attrKeys.toString()); - // attrDescription tends not to be useful, so give the fully qualified name too. - String help = attrDescription + " (" + beanName + attrName + ")"; - String attrNameSnakeCase = toSnakeAndLowerCase(attrName); - for (HmilyMetricsConfig.HmilyJmxConfig.Rule rule : config.getRules()) { - Matcher matcher = null; - String matchName = beanName + (rule.isAttrNameSnakeCase() ? attrNameSnakeCase : attrName); - if (rule.getPattern() != null) { - matcher = rule.getPattern().matcher(matchName + ": " + beanObject); - if (!matcher.matches()) { - continue; - } - } - Number value; - Object beanValue = beanObject; - if (rule.getValue() != null && !rule.getValue().isEmpty()) { - assert matcher != null; - String val = matcher.replaceAll(rule.getValue()); - - try { - beanValue = Double.valueOf(val); - } catch (NumberFormatException e) { - LOGGER.fine("Unable to parse configured value '" + val + "' to number for bean: " + beanName + attrName + ": " + beanValue); - return; - } - } - if (beanValue instanceof Number) { - value = ((Number) beanValue).doubleValue() * rule.getValueFactor(); - } else if (beanValue instanceof Boolean) { - value = (Boolean) beanValue ? 1 : 0; - } else { - LOGGER.fine("Ignoring unsupported bean: " + beanName + attrName + ": " + beanValue); - return; - } - // If there's no name provided, use default export format. - if (rule.getName() == null) { - defaultExport(domain, beanProperties, attrKeys, rule.isAttrNameSnakeCase() ? attrNameSnakeCase : attrName, help, value, Type.valueOf(rule.getType().name())); - return; - } - - // Matcher is set below here due to validation in the constructor. - assert matcher != null; - String name = safeName(matcher.replaceAll(rule.getName())); - if (name.isEmpty()) { - return; - } - if (config.isLowercaseOutputName()) { - name = name.toLowerCase(); - } - // Set the help. - if (rule.getHelp() != null) { - help = matcher.replaceAll(rule.getHelp()); - } - // Set the labels. - ArrayList labelNames = new ArrayList<>(); - ArrayList labelValues = new ArrayList<>(); - if (rule.getLabelNames() != null) { - for (int i = 0; i < rule.getLabelNames().size(); i++) { - final String unsafeLabelName = rule.getLabelNames().get(i); - final String labelValReplacement = rule.getLabelValues().get(i); - String labelName = safeName(matcher.replaceAll(unsafeLabelName)); - String labelValue = matcher.replaceAll(labelValReplacement); - if (config.isLowercaseOutputName()) { - labelName = labelName.toLowerCase(); - } - if (!labelName.isEmpty() && !labelValue.isEmpty()) { - labelNames.add(labelName); - labelValues.add(labelValue); - } - } - } - // Add to samples. - LOGGER.fine("add metric sample: " + name + " " + labelNames + " " + labelValues + " " + value.doubleValue()); - addSample(new MetricFamilySamples.Sample(name, labelNames, labelValues, value.doubleValue()), Type.valueOf(rule.getType().name()), help); - return; - } - } - } -} diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxMBeanPropertyCache.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxMBeanPropertyCache.java deleted file mode 100644 index ade3293f..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxMBeanPropertyCache.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.collector; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.management.ObjectName; - -/** - * This object stores a mapping of mBean objectNames to mBean key property lists. The main purpose of it is to reduce - * the frequency with which we invoke PROPERTY_PATTERN when discovering mBeans. - * - * @author xiaoyu - */ -public class JmxMBeanPropertyCache { - - private static final Pattern PROPERTY_PATTERN = Pattern.compile( - "([^,=:*?]+)" - + "=" - + "(" - + "\"" - + "(?:" - + "[^\\\\\"]*" - + "(?:\\\\.)?" - + ")*" - + "\"" - + "|" - + "[^,=:\"]*" - + ")"); - - // Implement a version of ObjectName.getKeyPropertyList that returns the - // properties in the ordered they were added (the ObjectName stores them - // in the order they were added). - private final Map> keyPropertiesPerBean; - - /** - * Instantiates a new Jmx m bean property cache. - */ - public JmxMBeanPropertyCache() { - this.keyPropertiesPerBean = new ConcurrentHashMap<>(); - } - - /** - * Gets key property list. - * - * @param mbeanName the mbean name - * @return the key property list - */ - public Map getKeyPropertyList(final ObjectName mbeanName) { - Map keyProperties = keyPropertiesPerBean.get(mbeanName); - if (keyProperties == null) { - keyProperties = new LinkedHashMap<>(); - String properties = mbeanName.getKeyPropertyListString(); - Matcher match = PROPERTY_PATTERN.matcher(properties); - while (match.lookingAt()) { - keyProperties.put(match.group(1), match.group(2)); - properties = properties.substring(match.end()); - if (properties.startsWith(",")) { - properties = properties.substring(1); - } - match.reset(properties); - } - keyPropertiesPerBean.put(mbeanName, keyProperties); - } - return keyProperties; - } - - /** - * Only keep m beans. - * - * @param latestBeans the latest beans - */ - public void onlyKeepMBeans(final Set latestBeans) { - for (ObjectName prevName : keyPropertiesPerBean.keySet()) { - if (!latestBeans.contains(prevName)) { - keyPropertiesPerBean.remove(prevName); - } - } - } -} diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxScraper.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxScraper.java deleted file mode 100644 index d8870b81..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/JmxScraper.java +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.collector; - -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import java.util.logging.Level; -import java.util.logging.Logger; -import javax.management.Attribute; -import javax.management.AttributeList; -import javax.management.InstanceNotFoundException; -import javax.management.JMException; -import javax.management.MBeanAttributeInfo; -import javax.management.MBeanInfo; -import javax.management.MBeanServerConnection; -import javax.management.ObjectInstance; -import javax.management.ObjectName; -import javax.management.ReflectionException; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeType; -import javax.management.openmbean.TabularData; -import javax.management.openmbean.TabularType; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXServiceURL; -import javax.management.remote.rmi.RMIConnectorServer; -import javax.naming.Context; -import javax.rmi.ssl.SslRMIClientSocketFactory; - -/** - * The type Jmx scraper. - * - * @author xiaoyu - */ -public class JmxScraper { - - private static final Logger LOGGER = Logger.getLogger(JmxScraper.class.getName()); - - private final MBeanReceiver receiver; - - private final String jmxUrl; - - private final String username; - - private final String password; - - private final boolean ssl; - - private final List whitelistObjectNames; - - private final List blacklistObjectNames; - - private final JmxMBeanPropertyCache jmxMBeanPropertyCache; - - /** - * Instantiates a new Jmx scraper. - * - * @param jmxUrl the jmx url - * @param username the username - * @param password the password - * @param ssl the ssl - * @param whitelistObjectNames the whitelist object names - * @param blacklistObjectNames the blacklist object names - * @param receiver the receiver - * @param jmxMBeanPropertyCache the jmx m bean property cache - */ - public JmxScraper(final String jmxUrl, final String username, final String password, final boolean ssl, - final List whitelistObjectNames, final List blacklistObjectNames, - final MBeanReceiver receiver, final JmxMBeanPropertyCache jmxMBeanPropertyCache) { - this.jmxUrl = jmxUrl; - this.receiver = receiver; - this.username = username; - this.password = password; - this.ssl = ssl; - this.whitelistObjectNames = whitelistObjectNames; - this.blacklistObjectNames = blacklistObjectNames; - this.jmxMBeanPropertyCache = jmxMBeanPropertyCache; - } - - private static void logScrape(final ObjectName mbeanName, final Set names, final String msg) { - logScrape(mbeanName + "_" + names, msg); - } - - private static void logScrape(final ObjectName mbeanName, final MBeanAttributeInfo attr, final String msg) { - logScrape(mbeanName + "'_'" + attr.getName(), msg); - } - - private static void logScrape(final String name, final String msg) { - LOGGER.log(Level.FINE, "scrape: '" + name + "': " + msg); - } - - /** - * Get a list of mbeans on host_port and scrape their values. - * Values are passed to the receiver in a single thread. - * - * @throws IOException the exception - */ - public void doScrape() throws IOException { - MBeanServerConnection beanConn; - JMXConnector jmxc = null; - if (jmxUrl.isEmpty()) { - beanConn = ManagementFactory.getPlatformMBeanServer(); - } else { - Map environment = new HashMap<>(); - if (username != null && username.length() != 0 && password != null && password.length() != 0) { - String[] credent = new String[]{username, password}; - environment.put(JMXConnector.CREDENTIALS, credent); - } - if (ssl) { - environment.put(Context.SECURITY_PROTOCOL, "ssl"); - SslRMIClientSocketFactory clientSocketFactory = new SslRMIClientSocketFactory(); - environment.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, clientSocketFactory); - environment.put("com.sun.jndi.rmi.factory.socket", clientSocketFactory); - } - - jmxc = JMXConnectorFactory.connect(new JMXServiceURL(jmxUrl), environment); - beanConn = jmxc.getMBeanServerConnection(); - } - try { - // Query MBean names, see #89 for reasons queryMBeans() is used instead of queryNames() - Set mBeanNames = new HashSet<>(); - for (ObjectName name : whitelistObjectNames) { - for (ObjectInstance instance : beanConn.queryMBeans(name, null)) { - mBeanNames.add(instance.getObjectName()); - } - } - - for (ObjectName name : blacklistObjectNames) { - for (ObjectInstance instance : beanConn.queryMBeans(name, null)) { - mBeanNames.remove(instance.getObjectName()); - } - } - - // Now that we have *only* the whitelisted mBeans, remove any old ones from the cache: - jmxMBeanPropertyCache.onlyKeepMBeans(mBeanNames); - - for (ObjectName objectName : mBeanNames) { - long start = System.nanoTime(); - scrapeBean(beanConn, objectName); - LOGGER.fine("TIME: " + (System.nanoTime() - start) + " ns for " + objectName.toString()); - } - } finally { - if (jmxc != null) { - jmxc.close(); - } - } - } - - private void scrapeBean(final MBeanServerConnection beanConn, final ObjectName mbeanName) { - MBeanInfo info; - try { - info = beanConn.getMBeanInfo(mbeanName); - } catch (IOException | JMException e) { - logScrape(mbeanName.toString(), "getMBeanInfo Fail: " + e); - return; - } - MBeanAttributeInfo[] attrInfos = info.getAttributes(); - - Map name2AttrInfo = new LinkedHashMap<>(); - for (MBeanAttributeInfo attr : attrInfos) { - if (!attr.isReadable()) { - logScrape(mbeanName, attr, "not readable"); - continue; - } - name2AttrInfo.put(attr.getName(), attr); - } - final AttributeList attributes; - try { - attributes = beanConn.getAttributes(mbeanName, name2AttrInfo.keySet().toArray(new String[0])); - if (attributes == null) { - logScrape(mbeanName.toString(), "getAttributes Fail: attributes are null"); - return; - } - } catch (InstanceNotFoundException | ReflectionException | IOException e) { - logScrape(mbeanName, name2AttrInfo.keySet(), "Fail: " + e); - return; - } - for (Attribute attribute : attributes.asList()) { - MBeanAttributeInfo attr = name2AttrInfo.get(attribute.getName()); - logScrape(mbeanName, attr, "process"); - processBeanValue(mbeanName.getDomain(), jmxMBeanPropertyCache.getKeyPropertyList(mbeanName), - new LinkedList<>(), attr.getName(), attr.getType(), attr.getDescription(), attribute.getValue()); - - } - } - - /** - * Recursive function for exporting the values of an mBean. - * JMX is a very open technology, without any prescribed way of declaring mBeans - * so this function tries to do a best-effort pass of getting the values/names - * out in a way it can be processed elsewhere easily. - */ - private void processBeanValue(final String domain, final Map beanProperties, - final LinkedList attrKeysParam, final String attrName, final String attrTypeParam, - final String attrDescription, final Object valueParam) { - LinkedList attrKeys = attrKeysParam; - String attrType = attrTypeParam; - Object value = valueParam; - if (value == null) { - logScrape(domain + beanProperties + attrName, "null"); - } else if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof java.util.Date) { - if (value instanceof java.util.Date) { - attrType = "java.lang.Double"; - value = ((java.util.Date) value).getTime() / 1000.0; - } - logScrape(domain + beanProperties + attrName, value.toString()); - this.receiver.recordBean(domain, beanProperties, attrKeys, attrName, attrType, attrDescription, value); - } else if (value instanceof CompositeData) { - logScrape(domain + beanProperties + attrName, "compositedata"); - CompositeData composite = (CompositeData) value; - CompositeType type = composite.getCompositeType(); - attrKeys = new LinkedList<>(attrKeys); - attrKeys.add(attrName); - for (String key : type.keySet()) { - String typ = type.getType(key).getTypeName(); - Object valu = composite.get(key); - processBeanValue(domain, beanProperties, attrKeys, key, typ, type.getDescription(), valu); - } - } else if (value instanceof TabularData) { - // I don't pretend to have a good understanding of TabularData. - // The real world usage doesn't appear to match how they were - // meant to be used according to the docs. I've only seen them - // used as 'key' 'value' pairs even when 'value' is itself a - // CompositeData of multiple values. - logScrape(domain + beanProperties + attrName, "tabulardata"); - TabularData tds = (TabularData) value; - TabularType tt = tds.getTabularType(); - List rowKeys = tt.getIndexNames(); - CompositeType type = tt.getRowType(); - Set valueKeys = new TreeSet<>(type.keySet()); - valueKeys.removeAll(rowKeys); - LinkedList extendedAttrKeys = new LinkedList<>(attrKeys); - extendedAttrKeys.add(attrName); - for (Object valu : tds.values()) { - if (valu instanceof CompositeData) { - CompositeData composite = (CompositeData) valu; - Map rowKeyMap = new LinkedHashMap<>(beanProperties); - String resultKey; - for (String rowKey : rowKeys) { - resultKey = rowKey; - Object obj = composite.get(resultKey); - if (obj != null) { - // Nested tabulardata will repeat the 'key' label, so - // append a suffix to distinguish each. - while (rowKeyMap.containsKey(resultKey)) { - resultKey = resultKey + "_"; - } - rowKeyMap.put(resultKey, obj.toString()); - } - } - for (String valueIdx : valueKeys) { - LinkedList attrNames = extendedAttrKeys; - String typ = type.getType(valueIdx).getTypeName(); - String name = valueIdx; - if ("value".equalsIgnoreCase(valueIdx.toLowerCase())) { - // Skip appending 'value' to the name - attrNames = attrKeys; - name = attrName; - } - processBeanValue(domain, rowKeyMap, attrNames, name, typ, type.getDescription(), composite.get(valueIdx)); - } - } else { - logScrape(domain, "not a correct tabulardata format"); - } - } - } else if (value.getClass().isArray()) { - logScrape(domain, "arrays are unsupported"); - } else { - logScrape(domain + beanProperties, attrType + " is not exported"); - } - } -} - diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/MBeanReceiver.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/MBeanReceiver.java deleted file mode 100644 index 973aff16..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/collector/MBeanReceiver.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.collector; - -import java.util.LinkedList; -import java.util.Map; - -/** - * The interface M bean receiver. - * - * @author xiaoyu - */ -public interface MBeanReceiver { - - /** - * Record bean. - * - * @param domain the domain - * @param beanProperties the bean properties - * @param attrKeys the attr keys - * @param attrName the attr name - * @param attrType the attr type - * @param attrDescription the attr description - * @param value the value - */ - void recordBean(String domain, Map beanProperties, - LinkedList attrKeys, String attrName, String attrType, - String attrDescription, Object value); -} diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/counter/TransactionStatusCounterMetricsTracker.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/counter/TransactionStatusCounterMetricsTracker.java deleted file mode 100644 index 173804e3..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/counter/TransactionStatusCounterMetricsTracker.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.counter; - -import io.prometheus.client.Counter; -import org.dromara.hmily.metrics.api.CounterMetricsTracker; -import org.dromara.hmily.metrics.enums.MetricsLabelEnum; - -/** - * Transaction counter metrics tracker. - */ -public final class TransactionStatusCounterMetricsTracker implements CounterMetricsTracker { - - private static final Counter TRANSACTION_STATUS = Counter.build() - .name("transaction") - .labelNames("type", "role", "status") - .help("collect transaction status count") - .register(); - - @Override - public void inc(final double amount, final String... labelValues) { - TRANSACTION_STATUS.labels(labelValues).inc(amount); - } - - @Override - public String metricsLabel() { - return MetricsLabelEnum.TRANSACTION_STATUS.getName(); - } -} diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/counter/TransactionTotalCounterMetricsTracker.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/counter/TransactionTotalCounterMetricsTracker.java deleted file mode 100644 index fdc2aee3..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/counter/TransactionTotalCounterMetricsTracker.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.counter; - -import io.prometheus.client.Counter; -import org.dromara.hmily.metrics.api.CounterMetricsTracker; -import org.dromara.hmily.metrics.enums.MetricsLabelEnum; - -/** - * Request total counter metrics tracker. - */ -public final class TransactionTotalCounterMetricsTracker implements CounterMetricsTracker { - - private static final Counter TRANSACTION_TOTAL = Counter.build() - .name("transaction_total") - .labelNames("type") - .help("hmily request total count") - .register(); - - @Override - public void inc(final double amount, final String... labelValues) { - TRANSACTION_TOTAL.labels(labelValues).inc(amount); - } - - @Override - public String metricsLabel() { - return MetricsLabelEnum.TRANSACTION_TOTAL.getName(); - } -} - diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/histogram/PrometheusHistogramMetricsTrackerDelegate.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/histogram/PrometheusHistogramMetricsTrackerDelegate.java deleted file mode 100644 index 845c7c95..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/histogram/PrometheusHistogramMetricsTrackerDelegate.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.histogram; - -import io.prometheus.client.Histogram; -import lombok.RequiredArgsConstructor; -import org.dromara.hmily.metrics.api.HistogramMetricsTrackerDelegate; - -/** - * Prometheus histogram metrics tracker delegate. - * - * @author xiaoyu - */ -@RequiredArgsConstructor -public final class PrometheusHistogramMetricsTrackerDelegate implements HistogramMetricsTrackerDelegate { - - private final Histogram.Timer timer; - - @Override - public void observeDuration() { - timer.observeDuration(); - } -} - diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/histogram/TransactionLatencyHistogramMetricsTracker.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/histogram/TransactionLatencyHistogramMetricsTracker.java deleted file mode 100644 index 2f3ebda0..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/histogram/TransactionLatencyHistogramMetricsTracker.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.histogram; - -import io.prometheus.client.Histogram; -import org.dromara.hmily.metrics.api.HistogramMetricsTracker; -import org.dromara.hmily.metrics.api.HistogramMetricsTrackerDelegate; -import org.dromara.hmily.metrics.enums.MetricsLabelEnum; - -/** - * Transaction latency histogram metrics tracker. - * - * @author xiaoyu - */ -public final class TransactionLatencyHistogramMetricsTracker implements HistogramMetricsTracker { - - private static final Histogram TRANSACTION_LATENCY = Histogram.build() - .labelNames("type") - .name("transaction_latency_histogram_millis").help("Transaction Latency Histogram Millis (ms)") - .register(); - - @Override - public HistogramMetricsTrackerDelegate startTimer(final String... labelValues) { - Histogram.Timer timer = TRANSACTION_LATENCY.labels(labelValues).startTimer(); - return new PrometheusHistogramMetricsTrackerDelegate(timer); - } - - @Override - public String metricsLabel() { - return MetricsLabelEnum.TRANSACTION_LATENCY.getName(); - } -} - diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/summary/PrometheusSummaryMetricsTrackerDelegate.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/summary/PrometheusSummaryMetricsTrackerDelegate.java deleted file mode 100644 index 88df1d8a..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/summary/PrometheusSummaryMetricsTrackerDelegate.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.summary; - -import io.prometheus.client.Summary; -import lombok.RequiredArgsConstructor; -import org.dromara.hmily.metrics.api.SummaryMetricsTrackerDelegate; - -/** - * Prometheus summary metrics tracker delegate. - * - * @author xiaoyu - */ -@RequiredArgsConstructor -public final class PrometheusSummaryMetricsTrackerDelegate implements SummaryMetricsTrackerDelegate { - - private final Summary.Timer timer; - - @Override - public void observeDuration() { - timer.observeDuration(); - } -} - diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/summary/TransactionLatencySummaryMetricsTracker.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/summary/TransactionLatencySummaryMetricsTracker.java deleted file mode 100644 index 0efb9033..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/impl/summary/TransactionLatencySummaryMetricsTracker.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.impl.summary; - -import io.prometheus.client.Summary; -import java.util.concurrent.TimeUnit; -import org.dromara.hmily.metrics.api.SummaryMetricsTracker; -import org.dromara.hmily.metrics.api.SummaryMetricsTrackerDelegate; -import org.dromara.hmily.metrics.enums.MetricsLabelEnum; - -/** - * Transaction latency summary metrics tracker. - * - * @author xiaoyu - */ -public final class TransactionLatencySummaryMetricsTracker implements SummaryMetricsTracker { - - private static final Summary TRANSACTION_LATENCY = Summary.build() - .name("transaction_latency_summary_millis").labelNames("type") - .help("Requests Latency Summary Millis (ms)") - .quantile(0.5, 0.05) - .quantile(0.95, 0.01) - .quantile(0.99, 0.001) - .maxAgeSeconds(TimeUnit.MINUTES.toSeconds(5)) - .ageBuckets(5) - .register(); - - @Override - public SummaryMetricsTrackerDelegate startTimer(final String... labelValues) { - Summary.Timer timer = TRANSACTION_LATENCY.labels(labelValues).startTimer(); - return new PrometheusSummaryMetricsTrackerDelegate(timer); - } - - @Override - public String metricsLabel() { - return MetricsLabelEnum.TRANSACTION_LATENCY.getName(); - } -} - diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/register/PrometheusMetricsRegister.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/register/PrometheusMetricsRegister.java new file mode 100644 index 00000000..2350b39a --- /dev/null +++ b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/register/PrometheusMetricsRegister.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.dromara.hmily.metrics.prometheus.register; + +import io.prometheus.client.Counter; +import io.prometheus.client.Gauge; +import io.prometheus.client.Histogram; +import lombok.extern.slf4j.Slf4j; +import org.dromara.hmily.metrics.spi.MetricsRegister; +import org.dromara.hmily.spi.HmilySPI; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Prometheus metrics register. + */ +@Slf4j +@HmilySPI("prometheus") +public final class PrometheusMetricsRegister implements MetricsRegister { + + private static final Map COUNTER_MAP = new ConcurrentHashMap<>(); + + private static final Map GAUGE_MAP = new ConcurrentHashMap<>(); + + private static final Map HISTOGRAM_MAP = new ConcurrentHashMap<>(); + + /** + * Get instance prometheus metrics register. + * + * @return the prometheus metrics register + */ + public static PrometheusMetricsRegister getInstance() { + return PrometheusMetricsRegisterHolder.INSTANCE; + } + + @Override + public void registerCounter(final String name, final String[] labelNames, final String document) { + if (!COUNTER_MAP.containsKey(name)) { + Counter.Builder builder = Counter.build().name(name).help(document); + if (null != labelNames) { + builder.labelNames(labelNames); + } + COUNTER_MAP.put(name, builder.register()); + } + } + + @Override + public void registerGauge(final String name, final String[] labelNames, final String document) { + if (!GAUGE_MAP.containsKey(name)) { + Gauge.Builder builder = Gauge.build().name(name).help(document); + if (null != labelNames) { + builder.labelNames(labelNames); + } + GAUGE_MAP.put(name, builder.register()); + } + } + + @Override + public void registerHistogram(final String name, final String[] labelNames, final String document) { + if (!HISTOGRAM_MAP.containsKey(name)) { + Histogram.Builder builder = Histogram.build().name(name).help(document); + if (null != labelNames) { + builder.labelNames(labelNames); + } + HISTOGRAM_MAP.put(name, builder.register()); + } + } + + @Override + public void counterIncrement(final String name, final String[] labelValues, final long count) { + Counter counter = COUNTER_MAP.get(name); + if (null != labelValues) { + counter.labels(labelValues).inc(count); + } else { + counter.inc(count); + } + } + + @Override + public void gaugeIncrement(final String name, final String[] labelValues) { + Gauge gauge = GAUGE_MAP.get(name); + if (null != labelValues) { + gauge.labels(labelValues).inc(); + } else { + gauge.inc(); + } + } + + @Override + public void gaugeDecrement(final String name, final String[] labelValues) { + Gauge gauge = GAUGE_MAP.get(name); + if (null != labelValues) { + gauge.labels(labelValues).dec(); + } else { + gauge.dec(); + } + } + + @Override + public void recordTime(final String name, final String[] labelValues, final long duration) { + Histogram histogram = HISTOGRAM_MAP.get(name); + if (null != labelValues) { + histogram.labels(labelValues).observe(duration); + } else { + histogram.observe(duration); + } + } + + private static class PrometheusMetricsRegisterHolder { + + private static final PrometheusMetricsRegister INSTANCE = new PrometheusMetricsRegister(); + } +} diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/PrometheusMetricsTrackerManager.java b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/service/PrometheusBootService.java similarity index 52% rename from hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/PrometheusMetricsTrackerManager.java rename to hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/service/PrometheusBootService.java index fdf68999..cc793514 100644 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/PrometheusMetricsTrackerManager.java +++ b/hmily-metrics/hmily-metrics-prometheus/src/main/java/org/dromara/hmily/metrics/prometheus/service/PrometheusBootService.java @@ -15,24 +15,26 @@ * limitations under the License. */ -package org.dromara.hmily.metrics.prometheus; +package org.dromara.hmily.metrics.prometheus.service; import io.prometheus.client.CollectorRegistry; import io.prometheus.client.exporter.HTTPServer; import io.prometheus.client.hotspot.DefaultExports; +import io.prometheus.jmx.JmxCollector; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.dromara.hmily.config.api.entity.HmilyMetricsConfig; +import org.dromara.hmily.metrics.prometheus.collector.BuildInfoCollector; +import org.dromara.hmily.metrics.reporter.MetricsReporter; +import org.dromara.hmily.metrics.spi.MetricsBootService; +import org.dromara.hmily.metrics.spi.MetricsRegister; +import org.dromara.hmily.spi.HmilySPI; + +import javax.management.MalformedObjectNameException; import java.io.IOException; import java.net.InetSocketAddress; import java.util.concurrent.atomic.AtomicBoolean; -import javax.management.MalformedObjectNameException; -import lombok.Getter; -import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; -import org.dromara.hmily.config.api.entity.HmilyMetricsConfig; -import org.dromara.hmily.metrics.api.MetricsTrackerFactory; -import org.dromara.hmily.metrics.prometheus.impl.collector.BuildInfoCollector; -import org.dromara.hmily.metrics.prometheus.impl.collector.JmxCollector; -import org.dromara.hmily.metrics.spi.MetricsTrackerManager; -import org.dromara.hmily.spi.HmilySPI; /** * Prometheus metrics tracker manager. @@ -40,31 +42,43 @@ import org.dromara.hmily.spi.HmilySPI; @Getter @Slf4j @HmilySPI("prometheus") -public final class PrometheusMetricsTrackerManager implements MetricsTrackerManager { - - private final MetricsTrackerFactory metricsTrackerFactory = new PrometheusMetricsTrackerFactory(); +public final class PrometheusBootService implements MetricsBootService { private HTTPServer server; private volatile AtomicBoolean registered = new AtomicBoolean(false); - @SneakyThrows(IOException.class) @Override - public void start(final HmilyMetricsConfig metricsConfig) { - register(metricsConfig.getJmxConfig()); - InetSocketAddress inetSocketAddress; - if ("".equals(metricsConfig.getHost()) || null == metricsConfig.getHost()) { - inetSocketAddress = new InetSocketAddress(metricsConfig.getPort()); - } else { - inetSocketAddress = new InetSocketAddress(metricsConfig.getHost(), metricsConfig.getPort()); - } - server = new HTTPServer(inetSocketAddress, CollectorRegistry.defaultRegistry, true); - log.info("you start prometheus metrics http server host is :{}, port is :{} ", inetSocketAddress.getHostString(), inetSocketAddress.getPort()); + public void start(final HmilyMetricsConfig metricsConfig, final MetricsRegister register) { + startServer(metricsConfig); + MetricsReporter.register(register); } @Override public void stop() { - server.stop(); + if (server != null) { + server.stop(); + registered.set(false); + CollectorRegistry.defaultRegistry.clear(); + } + } + + private void startServer(final HmilyMetricsConfig metricsConfig) { + register(metricsConfig.getJmxConfig()); + int port = metricsConfig.getPort(); + String host = metricsConfig.getHost(); + InetSocketAddress inetSocketAddress; + if (null == host || "".equalsIgnoreCase(host)) { + inetSocketAddress = new InetSocketAddress(port); + } else { + inetSocketAddress = new InetSocketAddress(host, port); + } + try { + server = new HTTPServer(inetSocketAddress, CollectorRegistry.defaultRegistry, true); + log.info(String.format("Prometheus metrics HTTP server `%s:%s` start success.", inetSocketAddress.getHostString(), inetSocketAddress.getPort())); + } catch (final IOException ex) { + log.error("Prometheus metrics HTTP server start fail", ex); + } } private void register(final String jmxConfig) { @@ -72,11 +86,13 @@ public final class PrometheusMetricsTrackerManager implements MetricsTrackerMana return; } new BuildInfoCollector().register(); + DefaultExports.initialize(); try { - new JmxCollector(jmxConfig).register(); - DefaultExports.initialize(); + if (StringUtils.isNotEmpty(jmxConfig)) { + new JmxCollector(jmxConfig).register(); + } } catch (MalformedObjectNameException e) { - log.error("init jxm collector error", e); + log.error("init jmx collector error", e); } } } diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsBootService b/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsBootService new file mode 100644 index 00000000..52b427fa --- /dev/null +++ b/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsBootService @@ -0,0 +1 @@ +org.dromara.hmily.metrics.prometheus.service.PrometheusBootService diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsRegister b/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsRegister new file mode 100644 index 00000000..a53e238c --- /dev/null +++ b/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsRegister @@ -0,0 +1 @@ +org.dromara.hmily.metrics.prometheus.register.PrometheusMetricsRegister diff --git a/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsTrackerManager b/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsTrackerManager deleted file mode 100644 index 2a36915f..00000000 --- a/hmily-metrics/hmily-metrics-prometheus/src/main/resources/META-INF/hmily/org.dromara.hmily.metrics.spi.MetricsTrackerManager +++ /dev/null @@ -1 +0,0 @@ -org.dromara.hmily.metrics.prometheus.PrometheusMetricsTrackerManager diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/CounterMetricsTracker.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/CounterMetricsTracker.java deleted file mode 100644 index 6c37e8f5..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/CounterMetricsTracker.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -import org.dromara.hmily.metrics.enums.MetricsTypeEnum; - -/** - * Counter metrics tracker interface. - * - * @author xiaoyu - */ -public interface CounterMetricsTracker extends MetricsTracker { - - /** - * Increment the counter with label values by the given amount. - * - * @param amount amount - * @param labelValues label values - */ - void inc(double amount, String... labelValues); - - /** - * Metrics type. - * - * @return metrics type - */ - default String metricsType() { - return MetricsTypeEnum.COUNTER.name(); - } -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/GaugeMetricsTracker.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/GaugeMetricsTracker.java deleted file mode 100644 index f57c698c..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/GaugeMetricsTracker.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -import org.dromara.hmily.metrics.enums.MetricsTypeEnum; - -/** - * Gauge metrics tracker interface. - * - * @author xiaoyu - */ -public interface GaugeMetricsTracker extends MetricsTracker { - - /** - * Increment the Gauge with label values by the given amount. - * - * @param amount amount - * @param labelValues label values - */ - void inc(double amount, String... labelValues); - - /** - * Decrement the Gauge with label values by the given amount. - * - * @param amount amount - * @param labelValues label values - */ - void dec(double amount, String... labelValues); - - /** - * Metrics type. - * - * @return metrics type - */ - default String metricsType() { - return MetricsTypeEnum.GAUGE.name(); - } -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/HistogramMetricsTracker.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/HistogramMetricsTracker.java deleted file mode 100644 index 62dbfcf0..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/HistogramMetricsTracker.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -import org.dromara.hmily.metrics.enums.MetricsTypeEnum; - -/** - * Histogram metrics tracker. - * - * @author xiaoyu - */ -public interface HistogramMetricsTracker extends MetricsTracker { - - /** - * Start timer with histogram. - * - * @param labelValues label values - * @return histogram metrics tracker delegate - */ - default HistogramMetricsTrackerDelegate startTimer(String... labelValues) { - return new NoneHistogramMetricsTrackerDelegate(); - } - - /** - * Observe the given amount. - * - * @param amount amount - */ - default void observer(long amount) { - } - - /** - * Metrics type. - * - * @return metrics type - */ - default String metricsType() { - return MetricsTypeEnum.HISTOGRAM.name(); - } -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/HistogramMetricsTrackerDelegate.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/HistogramMetricsTrackerDelegate.java deleted file mode 100644 index de5669f1..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/HistogramMetricsTrackerDelegate.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -/** - * Histogram metrics tracker delegate. - * - * @author xiaoyu - */ -public interface HistogramMetricsTrackerDelegate { - - /** - * Observe amount of time since start time. - */ - default void observeDuration() { - } -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/MetricsTrackerFactory.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/MetricsTrackerFactory.java deleted file mode 100644 index d6b1e06f..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/MetricsTrackerFactory.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -import java.util.Optional; - -/** - * Metrics tracker factory. - * - * @author xiaoyu - */ -public interface MetricsTrackerFactory { - - /** - * Create of metrics tracker. - * - * @param metricsType metrics type - * @param metricsLabel metrics label - * @return metrics tracker - */ - Optional create(String metricsType, String metricsLabel); -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/NoneHistogramMetricsTrackerDelegate.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/NoneHistogramMetricsTrackerDelegate.java deleted file mode 100644 index cf579e94..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/NoneHistogramMetricsTrackerDelegate.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -/** - * The type None histogram metrics tracker delegate. - * - * @author xiaoyu - */ -public final class NoneHistogramMetricsTrackerDelegate implements HistogramMetricsTrackerDelegate { -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/NoneSummaryMetricsTrackerDelegate.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/NoneSummaryMetricsTrackerDelegate.java deleted file mode 100644 index 3d27f49b..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/NoneSummaryMetricsTrackerDelegate.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -/** - * None summary metrics tracker delegate. - * - * @author xiaoyu - */ -public final class NoneSummaryMetricsTrackerDelegate implements SummaryMetricsTrackerDelegate { -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/SummaryMetricsTracker.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/SummaryMetricsTracker.java deleted file mode 100644 index 979da4b7..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/SummaryMetricsTracker.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -import org.dromara.hmily.metrics.enums.MetricsTypeEnum; - -/** - * Summary metrics tracker. - * - * @author xiaoyu - */ -public interface SummaryMetricsTracker extends MetricsTracker { - - /** - * Start timer with summary. - * - * @param labelValues label values - * @return Summary metrics tracker delegate - */ - default SummaryMetricsTrackerDelegate startTimer(String... labelValues) { - return new NoneSummaryMetricsTrackerDelegate(); - } - - /** - * Observe the given amount. - * - * @param amount amount - */ - default void observer(long amount) { - } - - /** - * Metrics type. - * - * @return metrics type - */ - default String metricsType() { - return MetricsTypeEnum.SUMMARY.name(); - } -} diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/SummaryMetricsTrackerDelegate.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/SummaryMetricsTrackerDelegate.java deleted file mode 100644 index 243ee50d..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/SummaryMetricsTrackerDelegate.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.api; - -/** - * Summary metrics tracker delegate. - * - * @author xiaoyu - */ -public interface SummaryMetricsTrackerDelegate { - - /** - * Observe amount of time in seconds since start time. - */ - default void observeDuration() { - } -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/MetricsTracker.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/constant/LabelNames.java similarity index 63% rename from hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/MetricsTracker.java rename to hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/constant/LabelNames.java index 11d83138..bcf686fa 100644 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/api/MetricsTracker.java +++ b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/constant/LabelNames.java @@ -5,7 +5,7 @@ * The ASF licenses this file to You 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 @@ -15,27 +15,25 @@ * limitations under the License. */ -package org.dromara.hmily.metrics.api; +package org.dromara.hmily.metrics.constant; /** - * Metrics tracker. - * - * @author xiaoyu + * The Label names. */ -public interface MetricsTracker { +public final class LabelNames { /** - * Metrics label. - * - * @return metrics label + * The constant TRANSACTION_STATUS. */ - String metricsLabel(); + public static final String TRANSACTION_STATUS = "hmily_transaction_status"; /** - * Metrics type. - * - * @return metrics type + * The constant TRANSACTION_TOTAL. */ - String metricsType(); + public static final String TRANSACTION_TOTAL = "hmily_transaction_total"; + + /** + * The constant TRANSACTION_LATENCY. + */ + public static final String TRANSACTION_LATENCY = "hmily_transaction_latency_histogram_millis"; } - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricsLabelEnum.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/entity/Metric.java similarity index 69% rename from hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricsLabelEnum.java rename to hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/entity/Metric.java index 96993101..d231fc39 100644 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricsLabelEnum.java +++ b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/entity/Metric.java @@ -15,34 +15,26 @@ * limitations under the License. */ -package org.dromara.hmily.metrics.enums; +package org.dromara.hmily.metrics.entity; import lombok.Getter; import lombok.RequiredArgsConstructor; +import org.dromara.hmily.metrics.enums.MetricType; + +import java.util.List; /** - * Metrics label enum. - * - * @author xiaoyu + * Metric. */ -@RequiredArgsConstructor @Getter -public enum MetricsLabelEnum { +@RequiredArgsConstructor +public final class Metric { - /** - * transaction total metrics label. - */ - TRANSACTION_TOTAL("transaction_total"), - - /** - * transaction latency metrics label. - */ - TRANSACTION_LATENCY("transaction_latency"), - - /** - * Transaction status metrics label enum. - */ - TRANSACTION_STATUS("transaction_status"); + private final MetricType type; private final String name; + + private final String document; + + private final List labels; } diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricsTypeEnum.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricType.java similarity index 79% rename from hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricsTypeEnum.java rename to hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricType.java index 8ebbb18e..37b50ec2 100644 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricsTypeEnum.java +++ b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/enums/MetricType.java @@ -17,31 +17,28 @@ package org.dromara.hmily.metrics.enums; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + /** - * Metrics type enum. - * - * @author xiaoyu + * Metric type. */ -public enum MetricsTypeEnum { +@Getter +@RequiredArgsConstructor +public enum MetricType { /** - * Counter metrics type. + * Counter metric type. */ COUNTER, /** - * Gauge metrics type. + * Gauge metric type. */ GAUGE, /** - * Histogram metrics type. + * Histogram metric type. */ - HISTOGRAM, - - /** - * Summary metrics type. - */ - SUMMARY + HISTOGRAM } - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/reporter/MetricsReporter.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/reporter/MetricsReporter.java new file mode 100644 index 00000000..80b211c8 --- /dev/null +++ b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/reporter/MetricsReporter.java @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.dromara.hmily.metrics.reporter; + +import org.dromara.hmily.metrics.spi.MetricsRegister; +import org.dromara.hmily.metrics.entity.Metric; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; + +/** + * Metrics reporter. + */ +public final class MetricsReporter { + + private static MetricsRegister metricsRegister; + + /** + * Register. + * + * @param metricsRegister metrics register + */ + public static void register(final MetricsRegister metricsRegister) { + MetricsReporter.metricsRegister = metricsRegister; + } + + /** + * Register metrics. + * + * @param metrics metric collection + */ + public static void registerMetrics(final Collection metrics) { + for (Metric metric : metrics) { + switch (metric.getType()) { + case COUNTER: + registerCounter(metric.getName(), getLabelNames(metric.getLabels()), metric.getDocument()); + break; + case GAUGE: + registerGauge(metric.getName(), getLabelNames(metric.getLabels()), metric.getDocument()); + break; + case HISTOGRAM: + registerHistogram(metric.getName(), getLabelNames(metric.getLabels()), metric.getDocument()); + break; + default: + throw new RuntimeException("we not support metric registration for type: " + metric.getType()); + } + } + } + + /** + * Register counter. + * + * @param name name + * @param labelNames label names + * @param document document for counter + */ + public static void registerCounter(final String name, final String[] labelNames, final String document) { + Optional.ofNullable(metricsRegister).ifPresent(register -> register.registerCounter(name, labelNames, document)); + } + + /** + * Register counter. + * + * @param name name + * @param document document for counter + */ + public static void registerCounter(final String name, final String document) { + registerCounter(name, null, document); + } + + /** + * Register gauge. + * + * @param name name + * @param labelNames label names + * @param document document for gauge + */ + public static void registerGauge(final String name, final String[] labelNames, final String document) { + Optional.ofNullable(metricsRegister).ifPresent(register -> register.registerGauge(name, labelNames, document)); + } + + /** + * Register gauge. + * + * @param name name + * @param document document for gauge + */ + public static void registerGauge(final String name, final String document) { + registerGauge(name, null, document); + } + + /** + * Register histogram by label names. + * + * @param name name + * @param labelNames label names + * @param document document for histogram + */ + public static void registerHistogram(final String name, final String[] labelNames, final String document) { + Optional.ofNullable(metricsRegister).ifPresent(register -> register.registerHistogram(name, labelNames, document)); + } + + /** + * Register histogram. + * + * @param name name + * @param document document for histogram + */ + public static void registerHistogram(final String name, final String document) { + registerHistogram(name, null, document); + } + + /** + * Counter increment. + * + * @param name name + * @param labelValues label values + */ + public static void counterIncrement(final String name, final String[] labelValues) { + counterIncrement(name, labelValues, 1); + } + + /** + * Counter increment. + * + * @param name name + */ + public static void counterIncrement(final String name) { + counterIncrement(name, null, 1); + } + + /** + * Counter increment by count. + * + * @param name name + * @param labelValues label values + * @param count count + */ + public static void counterIncrement(final String name, final String[] labelValues, final long count) { + Optional.ofNullable(metricsRegister).ifPresent(register -> register.counterIncrement(name, labelValues, count)); + } + + /** + * Gauge increment. + * + * @param name name + * @param labelValues label values + */ + public static void gaugeIncrement(final String name, final String[] labelValues) { + Optional.ofNullable(metricsRegister).ifPresent(register -> register.gaugeIncrement(name, labelValues)); + } + + /** + * Gauge increment. + * + * @param name name + */ + public static void gaugeIncrement(final String name) { + gaugeIncrement(name, null); + } + + /** + * Gauge decrement. + * + * @param name name + * @param labelValues label values + */ + public static void gaugeDecrement(final String name, final String[] labelValues) { + Optional.ofNullable(metricsRegister).ifPresent(register -> register.gaugeDecrement(name, labelValues)); + } + + /** + * Gauge decrement. + * + * @param name name + */ + public static void gaugeDecrement(final String name) { + gaugeDecrement(name, null); + } + + /** + * Record time by duration. + * + * @param name name + * @param labelValues label values + * @param duration duration + */ + public static void recordTime(final String name, final String[] labelValues, final long duration) { + Optional.ofNullable(metricsRegister).ifPresent(register -> register.recordTime(name, labelValues, duration)); + } + + /** + * Record time by duration. + * + * @param name name + * @param duration duration + */ + public static void recordTime(final String name, final long duration) { + recordTime(name, null, duration); + } + + private static String[] getLabelNames(final List labels) { + return labels.toArray(new String[0]); + } +} diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsTrackerManager.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsBootService.java similarity index 77% rename from hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsTrackerManager.java rename to hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsBootService.java index b55b7331..548a5878 100644 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsTrackerManager.java +++ b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsBootService.java @@ -18,28 +18,19 @@ package org.dromara.hmily.metrics.spi; import org.dromara.hmily.config.api.entity.HmilyMetricsConfig; -import org.dromara.hmily.metrics.api.MetricsTrackerFactory; /** * Metrics tracker manager. - * - * @author xiaoyu */ -public interface MetricsTrackerManager { +public interface MetricsBootService { /** * Start metrics tracker. * * @param metricsConfig metrics config + * @param register the register */ - void start(HmilyMetricsConfig metricsConfig); - - /** - * Gets metrics tracker factory. - * - * @return metrics tracker factory - */ - MetricsTrackerFactory getMetricsTrackerFactory(); + void start(HmilyMetricsConfig metricsConfig, MetricsRegister register); /** * Stop metrics tracker. diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsHandlerFacade.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsHandlerFacade.java deleted file mode 100644 index 6c7cae43..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsHandlerFacade.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.spi; - -import java.util.function.Supplier; - -/** - * Metrics Handler facade. - * - * @author xiaoyu - */ -public interface MetricsHandlerFacade { - - /** - * Increment of counter metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - */ - void counterIncrement(String metricsLabel, String... labelValues); - - /** - * Increment of gauge metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - */ - void gaugeIncrement(String metricsLabel, String... labelValues); - - /** - * Decrement of gauge metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - */ - void gaugeDecrement(String metricsLabel, String... labelValues); - - /** - * Start timer of histogram metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - * @return histogram metrics tracker delegate - */ - Supplier histogramStartTimer(String metricsLabel, String... labelValues); - - /** - * Start timer of summary metrics tracker. - * - * @param metricsLabel metrics label - * @param labelValues label values - * @return summary metrics tracker delegate - */ - Supplier summaryStartTimer(String metricsLabel, String... labelValues); -} - diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsHandlerFacadeEngine.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsHandlerFacadeEngine.java deleted file mode 100644 index 60f259eb..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsHandlerFacadeEngine.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.spi; - -import java.util.Optional; -import org.dromara.hmily.spi.ExtensionLoaderFactory; - -/** - * The type Metrics handler facade engine. - * - * @author xiaoyu - */ -public final class MetricsHandlerFacadeEngine { - - /** - * Load MetricsHandlerFacade optional. - * - * @return the optional - */ - public static Optional load() { - return Optional.ofNullable(ExtensionLoaderFactory.load(MetricsHandlerFacade.class)); - } -} diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsInit.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsInit.java deleted file mode 100644 index 5dd73ac9..00000000 --- a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsInit.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.dromara.hmily.metrics.spi; - -import org.dromara.hmily.config.api.entity.HmilyMetricsConfig; - -/** - * The interface Metrics init. - * - * @author xiaoyu - */ -public interface MetricsInit extends AutoCloseable { - - /** - * Init. - * - * @param metricsConfig the metrics config - */ - void init(HmilyMetricsConfig metricsConfig); -} diff --git a/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsRegister.java b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsRegister.java new file mode 100644 index 00000000..c36aff3f --- /dev/null +++ b/hmily-metrics/hmily-metrics-spi/src/main/java/org/dromara/hmily/metrics/spi/MetricsRegister.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.dromara.hmily.metrics.spi; + +/** + * Metrics register. + */ +public interface MetricsRegister { + + /** + * Register gauge. + * + * @param name name + * @param labelNames label names + * @param document document for gauge + */ + void registerGauge(String name, String[] labelNames, String document); + + /** + * Register counter. + * + * @param name name + * @param labelNames label names + * @param document document for counter + */ + void registerCounter(String name, String[] labelNames, String document); + + /** + * Register histogram. + * + * @param name name + * @param labelNames label names + * @param document document for histogram + */ + void registerHistogram(String name, String[] labelNames, String document); + + /** + * Counter increment by count. + * + * @param name name + * @param labelValues label values + * @param count count + */ + void counterIncrement(String name, String[] labelValues, long count); + + /** + * Gauge increment. + * + * @param name name + * @param labelValues label values + */ + void gaugeIncrement(String name, String[] labelValues); + + /** + * Gauge decrement. + * + * @param name name + * @param labelValues label values + */ + void gaugeDecrement(String name, String[] labelValues); + + /** + * Record time by duration. + * + * @param name name + * @param labelValues label values + * @param duration duration + */ + void recordTime(String name, String[] labelValues, long duration); +} diff --git a/hmily-metrics/pom.xml b/hmily-metrics/pom.xml index 78ad6637..14a11e3d 100644 --- a/hmily-metrics/pom.xml +++ b/hmily-metrics/pom.xml @@ -20,8 +20,8 @@ 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"> - hmily org.dromara + hmily 2.1.2-SNAPSHOT 4.0.0 diff --git a/hmily-tac/hmily-tac-core/src/main/java/org/dromara/hmily/tac/core/handler/ParticipantHmilyTacTransactionHandler.java b/hmily-tac/hmily-tac-core/src/main/java/org/dromara/hmily/tac/core/handler/ParticipantHmilyTacTransactionHandler.java index 47412f09..7504a0de 100644 --- a/hmily-tac/hmily-tac-core/src/main/java/org/dromara/hmily/tac/core/handler/ParticipantHmilyTacTransactionHandler.java +++ b/hmily-tac/hmily-tac-core/src/main/java/org/dromara/hmily/tac/core/handler/ParticipantHmilyTacTransactionHandler.java @@ -28,8 +28,8 @@ import org.dromara.hmily.core.context.HmilyContextHolder; import org.dromara.hmily.core.context.HmilyTransactionContext; import org.dromara.hmily.core.repository.HmilyRepositoryStorage; import org.dromara.hmily.core.service.HmilyTransactionHandler; -import org.dromara.hmily.metrics.enums.MetricsLabelEnum; -import org.dromara.hmily.metrics.spi.MetricsHandlerFacadeEngine; +import org.dromara.hmily.metrics.constant.LabelNames; +import org.dromara.hmily.metrics.reporter.MetricsReporter; import org.dromara.hmily.repository.spi.entity.HmilyParticipant; import org.dromara.hmily.tac.core.transaction.HmilyTacParticipantCoordinator; @@ -46,6 +46,10 @@ public class ParticipantHmilyTacTransactionHandler implements HmilyTransactionHa private final HmilyTacParticipantCoordinator coordinator = HmilyTacParticipantCoordinator.getInstance(); + static { + MetricsReporter.registerCounter(LabelNames.TRANSACTION_STATUS, new String[]{"type", "role", "status"}, "collect hmily transaction count"); + } + @Override public Object handleTransaction(final ProceedingJoinPoint point, final HmilyTransactionContext context) throws Throwable { HmilyParticipant hmilyParticipant = null; @@ -69,14 +73,12 @@ public class ParticipantHmilyTacTransactionHandler implements HmilyTransactionHa HmilyContextHolder.remove(); } case CONFIRMING: - MetricsHandlerFacadeEngine.load().ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(), - TransTypeEnum.TAC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CONFIRMING.name())); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_STATUS, new String[]{TransTypeEnum.TAC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CONFIRMING.name()}); List confirmList = HmilyParticipantCacheManager.getInstance().get(context.getParticipantId()); coordinator.commitParticipant(confirmList, context.getParticipantId()); break; case CANCELING: - MetricsHandlerFacadeEngine.load().ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(), - TransTypeEnum.TAC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CANCELING.name())); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_STATUS, new String[]{TransTypeEnum.TAC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CANCELING.name()}); List cancelList = HmilyParticipantCacheManager.getInstance().get(context.getParticipantId()); coordinator.rollbackParticipant(cancelList, context.getParticipantId()); break; diff --git a/hmily-tac/hmily-tac-core/src/main/java/org/dromara/hmily/tac/core/handler/StarterHmilyTacTransactionHandler.java b/hmily-tac/hmily-tac-core/src/main/java/org/dromara/hmily/tac/core/handler/StarterHmilyTacTransactionHandler.java index 9b1335e4..2425f330 100644 --- a/hmily-tac/hmily-tac-core/src/main/java/org/dromara/hmily/tac/core/handler/StarterHmilyTacTransactionHandler.java +++ b/hmily-tac/hmily-tac-core/src/main/java/org/dromara/hmily/tac/core/handler/StarterHmilyTacTransactionHandler.java @@ -27,14 +27,13 @@ import org.dromara.hmily.core.disruptor.HmilyDisruptor; import org.dromara.hmily.core.disruptor.handler.HmilyTransactionEventConsumer; import org.dromara.hmily.core.service.HmilyTransactionHandler; import org.dromara.hmily.core.service.HmilyTransactionTask; -import org.dromara.hmily.metrics.enums.MetricsLabelEnum; -import org.dromara.hmily.metrics.spi.MetricsHandlerFacade; -import org.dromara.hmily.metrics.spi.MetricsHandlerFacadeEngine; +import org.dromara.hmily.metrics.constant.LabelNames; +import org.dromara.hmily.metrics.reporter.MetricsReporter; import org.dromara.hmily.repository.spi.entity.HmilyTransaction; import org.dromara.hmily.tac.core.transaction.HmilyTacTransactionManager; -import java.util.Optional; -import java.util.function.Supplier; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; /** @@ -48,6 +47,12 @@ public class StarterHmilyTacTransactionHandler implements HmilyTransactionHandle private final HmilyDisruptor disruptor; + static { + MetricsReporter.registerCounter(LabelNames.TRANSACTION_TOTAL, new String[]{"type"}, "hmily transaction total count"); + MetricsReporter.registerHistogram(LabelNames.TRANSACTION_LATENCY, "hmily transaction Latency Histogram Millis (ms)"); + } + + /** * Instantiates a new Starter hmily tac transaction handler. */ @@ -61,13 +66,9 @@ public class StarterHmilyTacTransactionHandler implements HmilyTransactionHandle public Object handleTransaction(final ProceedingJoinPoint point, final HmilyTransactionContext context) throws Throwable { Object returnValue; - Supplier histogramSupplier = null; - Optional metricsFacade = MetricsHandlerFacadeEngine.load(); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_TOTAL, new String[]{TransTypeEnum.TAC.name()}); + LocalDateTime starterTime = LocalDateTime.now(); try { - if (metricsFacade.isPresent()) { - metricsFacade.get().counterIncrement(MetricsLabelEnum.TRANSACTION_TOTAL.getName(), TransTypeEnum.TAC.name()); - histogramSupplier = metricsFacade.get().histogramStartTimer(MetricsLabelEnum.TRANSACTION_LATENCY.getName(), TransTypeEnum.TAC.name()); - } tm.begin(); try { //execute try @@ -76,8 +77,7 @@ public class StarterHmilyTacTransactionHandler implements HmilyTransactionHandle //if exception ,execute cancel final HmilyTransaction currentTransaction = tm.getHmilyTransaction(); disruptor.getProvider().onData(() -> { - metricsFacade.ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(), - TransTypeEnum.TAC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CANCELING.name())); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_STATUS, new String[]{TransTypeEnum.TAC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CANCELING.name()}); tm.rollback(currentTransaction); }); throw throwable; @@ -85,16 +85,13 @@ public class StarterHmilyTacTransactionHandler implements HmilyTransactionHandle // execute confirm final HmilyTransaction currentTransaction = tm.getHmilyTransaction(); disruptor.getProvider().onData(() -> { - metricsFacade.ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(), - TransTypeEnum.TAC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CONFIRMING.name())); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_STATUS, new String[]{TransTypeEnum.TAC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CONFIRMING.name()}); tm.commit(currentTransaction); }); } finally { HmilyContextHolder.remove(); tm.remove(); - if (null != histogramSupplier) { - histogramSupplier.get(); - } + MetricsReporter.recordTime(LabelNames.TRANSACTION_LATENCY, starterTime.until(LocalDateTime.now(), ChronoUnit.MILLIS)); } return returnValue; } diff --git a/hmily-tcc/src/main/java/org/dromara/hmily/tcc/handler/ParticipantHmilyTccTransactionHandler.java b/hmily-tcc/src/main/java/org/dromara/hmily/tcc/handler/ParticipantHmilyTccTransactionHandler.java index 193d60b6..0b0bae8f 100644 --- a/hmily-tcc/src/main/java/org/dromara/hmily/tcc/handler/ParticipantHmilyTccTransactionHandler.java +++ b/hmily-tcc/src/main/java/org/dromara/hmily/tcc/handler/ParticipantHmilyTccTransactionHandler.java @@ -28,8 +28,8 @@ import org.dromara.hmily.core.context.HmilyContextHolder; import org.dromara.hmily.core.context.HmilyTransactionContext; import org.dromara.hmily.core.repository.HmilyRepositoryStorage; import org.dromara.hmily.core.service.HmilyTransactionHandler; -import org.dromara.hmily.metrics.enums.MetricsLabelEnum; -import org.dromara.hmily.metrics.spi.MetricsHandlerFacadeEngine; +import org.dromara.hmily.metrics.constant.LabelNames; +import org.dromara.hmily.metrics.reporter.MetricsReporter; import org.dromara.hmily.repository.spi.entity.HmilyParticipant; import org.dromara.hmily.tcc.executor.HmilyTccTransactionExecutor; @@ -46,6 +46,10 @@ public class ParticipantHmilyTccTransactionHandler implements HmilyTransactionHa private final HmilyTccTransactionExecutor executor = HmilyTccTransactionExecutor.getInstance(); + static { + MetricsReporter.registerCounter(LabelNames.TRANSACTION_STATUS, new String[]{"type", "role", "status"}, "collect hmily transaction count"); + } + @Override public Object handleTransaction(final ProceedingJoinPoint point, final HmilyTransactionContext context) throws Throwable { HmilyParticipant hmilyParticipant = null; @@ -69,13 +73,11 @@ public class ParticipantHmilyTccTransactionHandler implements HmilyTransactionHa HmilyContextHolder.remove(); } case CONFIRMING: - MetricsHandlerFacadeEngine.load().ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(), - TransTypeEnum.TCC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CONFIRMING.name())); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_STATUS, new String[]{TransTypeEnum.TCC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CONFIRMING.name()}); List confirmList = HmilyParticipantCacheManager.getInstance().get(context.getParticipantId()); return executor.participantConfirm(confirmList, context.getParticipantId()); case CANCELING: - MetricsHandlerFacadeEngine.load().ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(), - TransTypeEnum.TCC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CANCELING.name())); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_STATUS, new String[]{TransTypeEnum.TCC.name(), HmilyRoleEnum.PARTICIPANT.name(), HmilyActionEnum.CANCELING.name()}); List cancelList = HmilyParticipantCacheManager.getInstance().get(context.getParticipantId()); return executor.participantCancel(cancelList, context.getParticipantId()); default: diff --git a/hmily-tcc/src/main/java/org/dromara/hmily/tcc/handler/StarterHmilyTccTransactionHandler.java b/hmily-tcc/src/main/java/org/dromara/hmily/tcc/handler/StarterHmilyTccTransactionHandler.java index cee2721a..db7d0857 100644 --- a/hmily-tcc/src/main/java/org/dromara/hmily/tcc/handler/StarterHmilyTccTransactionHandler.java +++ b/hmily-tcc/src/main/java/org/dromara/hmily/tcc/handler/StarterHmilyTccTransactionHandler.java @@ -28,14 +28,13 @@ import org.dromara.hmily.core.disruptor.handler.HmilyTransactionEventConsumer; import org.dromara.hmily.core.holder.HmilyTransactionHolder; import org.dromara.hmily.core.service.HmilyTransactionHandler; import org.dromara.hmily.core.service.HmilyTransactionTask; -import org.dromara.hmily.metrics.enums.MetricsLabelEnum; -import org.dromara.hmily.metrics.spi.MetricsHandlerFacade; -import org.dromara.hmily.metrics.spi.MetricsHandlerFacadeEngine; +import org.dromara.hmily.metrics.constant.LabelNames; +import org.dromara.hmily.metrics.reporter.MetricsReporter; import org.dromara.hmily.repository.spi.entity.HmilyTransaction; import org.dromara.hmily.tcc.executor.HmilyTccTransactionExecutor; -import java.util.Optional; -import java.util.function.Supplier; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; /** @@ -49,6 +48,11 @@ public class StarterHmilyTccTransactionHandler implements HmilyTransactionHandle private HmilyDisruptor disruptor; + static { + MetricsReporter.registerCounter(LabelNames.TRANSACTION_TOTAL, new String[]{"type"}, "hmily transaction total count"); + MetricsReporter.registerHistogram(LabelNames.TRANSACTION_LATENCY, "hmily transaction Latency Histogram Millis (ms)"); + } + public StarterHmilyTccTransactionHandler() { disruptor = new HmilyDisruptor<>(new HmilyTransactionEventConsumer(), Runtime.getRuntime().availableProcessors() << 1, HmilyDisruptor.DEFAULT_SIZE); @@ -59,13 +63,9 @@ public class StarterHmilyTccTransactionHandler implements HmilyTransactionHandle public Object handleTransaction(final ProceedingJoinPoint point, final HmilyTransactionContext context) throws Throwable { Object returnValue; - Supplier histogramSupplier = null; - Optional handlerFacade = MetricsHandlerFacadeEngine.load(); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_TOTAL, new String[]{TransTypeEnum.TCC.name()}); + LocalDateTime starterTime = LocalDateTime.now(); try { - if (handlerFacade.isPresent()) { - handlerFacade.get().counterIncrement(MetricsLabelEnum.TRANSACTION_TOTAL.getName(), TransTypeEnum.TCC.name()); - histogramSupplier = handlerFacade.get().histogramStartTimer(MetricsLabelEnum.TRANSACTION_LATENCY.getName(), TransTypeEnum.TCC.name()); - } HmilyTransaction hmilyTransaction = executor.preTry(point); try { //execute try @@ -76,8 +76,7 @@ public class StarterHmilyTccTransactionHandler implements HmilyTransactionHandle //if exception ,execute cancel final HmilyTransaction currentTransaction = HmilyTransactionHolder.getInstance().getCurrentTransaction(); disruptor.getProvider().onData(() -> { - handlerFacade.ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(), - TransTypeEnum.TCC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CANCELING.name())); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_STATUS, new String[]{TransTypeEnum.TCC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CANCELING.name()}); executor.globalCancel(currentTransaction); }); throw throwable; @@ -85,16 +84,13 @@ public class StarterHmilyTccTransactionHandler implements HmilyTransactionHandle //execute confirm final HmilyTransaction currentTransaction = HmilyTransactionHolder.getInstance().getCurrentTransaction(); disruptor.getProvider().onData(() -> { - handlerFacade.ifPresent(metricsHandlerFacade -> metricsHandlerFacade.counterIncrement(MetricsLabelEnum.TRANSACTION_STATUS.getName(), - TransTypeEnum.TCC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CONFIRMING.name())); + MetricsReporter.counterIncrement(LabelNames.TRANSACTION_STATUS, new String[]{TransTypeEnum.TCC.name(), HmilyRoleEnum.START.name(), HmilyActionEnum.CONFIRMING.name()}); executor.globalConfirm(currentTransaction); }); } finally { HmilyContextHolder.remove(); executor.remove(); - if (null != histogramSupplier) { - histogramSupplier.get(); - } + MetricsReporter.recordTime(LabelNames.TRANSACTION_LATENCY, starterTime.until(LocalDateTime.now(), ChronoUnit.MILLIS)); } return returnValue; }