From 200a8b1c0527eaff76e667293740a9e49b69cae2 Mon Sep 17 00:00:00 2001 From: Daydreamer-ia <2296032269@qq.com> Date: Sun, 9 Jun 2024 20:18:02 +0800 Subject: [PATCH 1/2] 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 | 17 +++++++ 6 files changed, 197 insertions(+), 8 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..3d561bc97f 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 @@ -25,16 +25,34 @@ 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 +64,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..8c19dd810a --- /dev/null +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/DefaultExporter.java @@ -0,0 +1,48 @@ +/* + * Copyright 1999-2024 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); + } + } + } + +} \ No newline at end of file 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..6a57ee5a71 --- /dev/null +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/node/metric/export/MetricExporter.java @@ -0,0 +1,37 @@ +/* + * Copyright 1999-2024 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); +} \ No newline at end of file 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..7c704d4cc4 --- /dev/null +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/MetricExporterTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 1999-2024 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.assertTrue; + +/** + * @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); + } + +} \ No newline at end of file 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..4f63b368a1 --- /dev/null +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/node/metric/TestMetricExporter.java @@ -0,0 +1,33 @@ +/* + * Copyright 1999-2024 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..1f5b6e0423 --- /dev/null +++ b/sentinel-core/src/test/resources/META-INF/services/com.alibaba.csp.sentinel.node.metric.export.MetricExporter @@ -0,0 +1,17 @@ +# +# Copyright 1999-2024 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. +# + +com.alibaba.csp.sentinel.node.metric.TestMetricExporter \ No newline at end of file From 567d04df830f57aaa70db712821d3dadc423d702 Mon Sep 17 00:00:00 2001 From: Daydreamer-ia <2296032269@qq.com> Date: Wed, 25 Sep 2024 21:55:28 +0800 Subject: [PATCH 2/2] add more log and fix log issue --- .../alibaba/csp/sentinel/node/metric/MetricTimerListener.java | 2 +- .../csp/sentinel/node/metric/export/DefaultExporter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 3d561bc97f..68a3de74a6 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 @@ -43,7 +43,7 @@ public class MetricTimerListener implements Runnable { try { instance = SpiLoader.of(MetricExporter.class).loadFirstInstance(); } catch (Throwable t) { - // ignore + RecordLog.info("[MetricTimerListener] Fail to load metric exporter", t); } if (instance == null) { MetricTimerListener.exporter = new DefaultExporter(); 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 index 8c19dd810a..35c3af1216 100644 --- 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 @@ -40,7 +40,7 @@ public void export(Map> metrics) { try { metricWriter.write(entry.getKey(), entry.getValue()); } catch (Exception e) { - RecordLog.warn("[MetricTimerListener] Write metric error", e); + RecordLog.warn("[DefaultExporter] Write metric error", e); } } }