From 143d34c553e9d4eb2860d60ed02f6b015e8f326e Mon Sep 17 00:00:00 2001 From: Daydreamer-ia <2296032269@qq.com> Date: Thu, 25 Jan 2024 15:34:31 +0800 Subject: [PATCH] feature: add metric exporter interface --- .../node/metric/MetricTimerListener.java | 32 +++++++++---- .../node/metric/export/DefaultExporter.java | 48 +++++++++++++++++++ .../node/metric/export/MetricExporter.java | 37 ++++++++++++++ .../node/metric/MetricExporterTest.java | 38 +++++++++++++++ .../node/metric/TestMetricExporter.java | 33 +++++++++++++ ...sentinel.node.metric.export.MetricExporter | 1 + 6 files changed, 180 insertions(+), 9 deletions(-) create mode 100644 sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/DefaultExporter.java create mode 100644 sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/MetricExporter.java create mode 100644 sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/MetricExporterTest.java create mode 100644 sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/TestMetricExporter.java create mode 100644 sentinel-core/src/test/resources/META-INF/services/com.alibaba.csp.sentinel.node.metric.export.MetricExporter diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricTimerListener.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricTimerListener.java index 9dda6c83d4..44e859e174 100755 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricTimerListener.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/MetricTimerListener.java @@ -22,19 +22,35 @@ import java.util.TreeMap; import com.alibaba.csp.sentinel.Constants; -import com.alibaba.csp.sentinel.config.SentinelConfig; import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.node.ClusterNode; +import com.alibaba.csp.sentinel.node.metric.export.DefaultExporter; +import com.alibaba.csp.sentinel.node.metric.export.MetricExporter; import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; import com.alibaba.csp.sentinel.slots.clusterbuilder.ClusterBuilderSlot; +import com.alibaba.csp.sentinel.spi.SpiLoader; /** * @author jialiang.linjl */ public class MetricTimerListener implements Runnable { - private static final MetricWriter metricWriter = new MetricWriter(SentinelConfig.singleMetricFileSize(), - SentinelConfig.totalMetricFileCount()); + private static MetricExporter exporter = null; + + static { + MetricExporter instance = null; + try { + instance = SpiLoader.of(MetricExporter.class).loadFirstInstance(); + } catch (Throwable t) { + // ignore + } + if (instance == null) { + MetricTimerListener.exporter = new DefaultExporter(); + } else { + MetricTimerListener.exporter = instance; + } + RecordLog.info("[MetricTimerListener] Active exporter: {}", MetricTimerListener.exporter.getClass()); + } @Override public void run() { @@ -46,12 +62,10 @@ public void run() { } aggregate(maps, Constants.ENTRY_NODE.metrics(), Constants.ENTRY_NODE); if (!maps.isEmpty()) { - for (Entry> entry : maps.entrySet()) { - try { - metricWriter.write(entry.getKey(), entry.getValue()); - } catch (Exception e) { - RecordLog.warn("[MetricTimerListener] Write metric error", e); - } + try { + exporter.export(maps); + } catch (Exception e) { + RecordLog.warn("[MetricTimerListener] Write metric error", e); } } } diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/DefaultExporter.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/DefaultExporter.java new file mode 100644 index 0000000000..23fb6a73f0 --- /dev/null +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/DefaultExporter.java @@ -0,0 +1,48 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.csp.sentinel.node.metric.export; + +import com.alibaba.csp.sentinel.config.SentinelConfig; +import com.alibaba.csp.sentinel.log.RecordLog; +import com.alibaba.csp.sentinel.node.metric.MetricNode; +import com.alibaba.csp.sentinel.node.metric.MetricWriter; + +import java.util.List; +import java.util.Map; + +/** + * Origin way to export metrics. + * + * @author Daydreamer-ia + */ +public class DefaultExporter implements MetricExporter { + + private static final MetricWriter metricWriter = new MetricWriter(SentinelConfig.singleMetricFileSize(), + SentinelConfig.totalMetricFileCount()); + + @Override + public void export(Map> metrics) { + for (Map.Entry> entry : metrics.entrySet()) { + try { + metricWriter.write(entry.getKey(), entry.getValue()); + } catch (Exception e) { + RecordLog.warn("[MetricTimerListener] Write metric error", e); + } + } + } + +} diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/MetricExporter.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/MetricExporter.java new file mode 100644 index 0000000000..55947e4d56 --- /dev/null +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/MetricExporter.java @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.csp.sentinel.node.metric.export; + +import com.alibaba.csp.sentinel.node.metric.MetricNode; + +import java.util.List; +import java.util.Map; + +/** + * Used to export metric. + * + * @author Daydreamer-ia + */ +public interface MetricExporter { + + /** + * export metrics. + * + * @param metrics metrics. + */ + void export(Map> metrics); +} diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/MetricExporterTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/MetricExporterTest.java new file mode 100644 index 0000000000..ef3fcbcfb7 --- /dev/null +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/MetricExporterTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.csp.sentinel.node.metric; + +import org.junit.Test; + +import java.lang.reflect.Field; + +import static org.junit.Assert.*; + +/** + * @author Daydreamer-ia. + */ +public class MetricExporterTest { + + @Test + public void testExporter() throws NoSuchFieldException, IllegalAccessException { + Field exporter = MetricTimerListener.class.getDeclaredField("exporter"); + exporter.setAccessible(true); + Object o = exporter.get(exporter); + assertTrue(o instanceof TestMetricExporter); + } + +} diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/TestMetricExporter.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/TestMetricExporter.java new file mode 100644 index 0000000000..6c2f27ddbd --- /dev/null +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/TestMetricExporter.java @@ -0,0 +1,33 @@ +/* + * Copyright 1999-2023 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.alibaba.csp.sentinel.node.metric; + +import com.alibaba.csp.sentinel.node.metric.export.MetricExporter; + +import java.util.List; +import java.util.Map; + +/** + * @author Daydreamer-ia + */ +public class TestMetricExporter implements MetricExporter { + + @Override + public void export(Map> metrics) { + + } +} \ No newline at end of file diff --git a/sentinel-core/src/test/resources/META-INF/services/com.alibaba.csp.sentinel.node.metric.export.MetricExporter b/sentinel-core/src/test/resources/META-INF/services/com.alibaba.csp.sentinel.node.metric.export.MetricExporter new file mode 100644 index 0000000000..23f2880a7e --- /dev/null +++ b/sentinel-core/src/test/resources/META-INF/services/com.alibaba.csp.sentinel.node.metric.export.MetricExporter @@ -0,0 +1 @@ +com.alibaba.csp.sentinel.node.metric.TestMetricExporter \ No newline at end of file