You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@skywalking.apache.org by pe...@apache.org on 2018/09/12 06:18:06 UTC

[incubator-skywalking] branch master updated: Support ThermodynamicIndicator (#1659)

This is an automated email from the ASF dual-hosted git repository.

pengys pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new 1936d38  Support ThermodynamicIndicator (#1659)
1936d38 is described below

commit 1936d38d163998762e66bbd3af8114a267bc1964
Author: 吴晟 Wu Sheng <wu...@foxmail.com>
AuthorDate: Wed Sep 12 14:18:02 2018 +0800

    Support ThermodynamicIndicator (#1659)
    
    * Add 3 cases for existed indicators.
    
    * Add Pxx indicator.
    
    * Support All in trace analysis listener.
    
    * Fix CI and add P99/95/90/75/50 to source ALL.
    
    * Add ThermodynamicIndicator and its test. Also ALL source Thermodynamic metric.
    
    * Try to fix CI about javadoc.
---
 .../core/analysis/generated/all/AllDispatcher.java |  10 ++
 .../generated/all/AllHeatmapIndicator.java         | 122 +++++++++++++++++++
 .../analysis/indicator/ThermodynamicIndicator.java | 129 +++++++++++++++++++++
 .../indicator/ThermodynamicIndicatorTest.java      | 109 +++++++++++++++++
 4 files changed, 370 insertions(+)

diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/generated/all/AllDispatcher.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/generated/all/AllDispatcher.java
index 486e518..c778992 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/generated/all/AllDispatcher.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/generated/all/AllDispatcher.java
@@ -35,6 +35,7 @@ public class AllDispatcher implements SourceDispatcher<All> {
         doAllP90(source);
         doAllP75(source);
         doAllP50(source);
+        doAllHeatmap(source);
     }
 
     private void doAllP99(All source) {
@@ -77,4 +78,13 @@ public class AllDispatcher implements SourceDispatcher<All> {
         indicator.combine(source.getLatency(), 10);
         IndicatorProcess.INSTANCE.in(indicator);
     }
+
+    private void doAllHeatmap(All source) {
+        AllHeatmapIndicator indicator = new AllHeatmapIndicator();
+
+
+        indicator.setTimeBucket(source.getTimeBucket());
+        indicator.combine(source.getLatency(), 100, 20);
+        IndicatorProcess.INSTANCE.in(indicator);
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/generated/all/AllHeatmapIndicator.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/generated/all/AllHeatmapIndicator.java
new file mode 100644
index 0000000..99909f5
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/generated/all/AllHeatmapIndicator.java
@@ -0,0 +1,122 @@
+/*
+ * 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.apache.skywalking.oap.server.core.analysis.generated.all;
+
+import java.util.*;
+import org.apache.skywalking.oap.server.core.alarm.AlarmMeta;
+import org.apache.skywalking.oap.server.core.alarm.AlarmSupported;
+import org.apache.skywalking.oap.server.core.analysis.indicator.*;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.IndicatorType;
+import org.apache.skywalking.oap.server.core.remote.annotation.StreamData;
+import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
+import org.apache.skywalking.oap.server.core.storage.annotation.*;
+import org.apache.skywalking.oap.server.core.storage.StorageBuilder;
+import org.apache.skywalking.oap.server.core.source.Scope;
+
+/**
+ * This class is auto generated. Please don't change this class manually.
+ *
+ * @author Observability Analysis Language code generator
+ */
+@IndicatorType
+@StreamData
+@StorageEntity(name = "all_heatmap", builder = AllHeatmapIndicator.Builder.class)
+public class AllHeatmapIndicator extends ThermodynamicIndicator implements AlarmSupported {
+
+
+    @Override public String id() {
+        String splitJointId = String.valueOf(getTimeBucket());
+        return splitJointId;
+    }
+
+    @Override public int hashCode() {
+        int result = 17;
+        result = 31 * result + (int)getTimeBucket();
+        return result;
+    }
+
+    @Override public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+
+        AllHeatmapIndicator indicator = (AllHeatmapIndicator)obj;
+
+        if (getTimeBucket() != indicator.getTimeBucket())
+            return false;
+
+        return true;
+    }
+
+    @Override public RemoteData.Builder serialize() {
+        RemoteData.Builder remoteBuilder = RemoteData.newBuilder();
+
+        remoteBuilder.setDataLongs(0, getTimeBucket());
+
+
+        remoteBuilder.setDataIntegers(0, getStep());
+        remoteBuilder.setDataIntegers(1, getNumOfSteps());
+        getDetailGroup().forEach(element -> remoteBuilder.addDataIntLongPairList(element.serialize()));
+
+        return remoteBuilder;
+    }
+
+    @Override public void deserialize(RemoteData remoteData) {
+
+        setTimeBucket(remoteData.getDataLongs(0));
+
+
+        setStep(remoteData.getDataIntegers(0));
+        setNumOfSteps(remoteData.getDataIntegers(1));
+
+        setDetailGroup(new ArrayList<>(30));
+        remoteData.getDataIntLongPairListList().forEach(element -> {
+            getDetailGroup().add(new IntKeyLongValue(element.getKey(), element.getValue()));
+        });
+
+    }
+
+    @Override public AlarmMeta getAlarmMeta() {
+        return new AlarmMeta("All_heatmap", Scope.All);
+    }
+
+    public static class Builder implements StorageBuilder<AllHeatmapIndicator> {
+
+        @Override public Map<String, Object> data2Map(AllHeatmapIndicator storageData) {
+            Map<String, Object> map = new HashMap<>();
+            map.put("step", storageData.getStep());
+            map.put("num_of_steps", storageData.getNumOfSteps());
+            map.put("detail_group", storageData.getDetailGroup());
+            map.put("time_bucket", storageData.getTimeBucket());
+            return map;
+        }
+
+        @Override public AllHeatmapIndicator map2Data(Map<String, Object> dbMap) {
+            AllHeatmapIndicator indicator = new AllHeatmapIndicator();
+            indicator.setStep(((Number)dbMap.get("step")).intValue());
+            indicator.setNumOfSteps(((Number)dbMap.get("num_of_steps")).intValue());
+            indicator.setDetailGroup((List)dbMap.get("detail_group"));
+            indicator.setTimeBucket(((Number)dbMap.get("time_bucket")).longValue());
+            return indicator;
+        }
+    }
+}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/ThermodynamicIndicator.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/ThermodynamicIndicator.java
new file mode 100644
index 0000000..518a16b
--- /dev/null
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/indicator/ThermodynamicIndicator.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.apache.skywalking.oap.server.core.analysis.indicator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.Arg;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.Entrance;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.IndicatorOperator;
+import org.apache.skywalking.oap.server.core.analysis.indicator.annotation.SourceFrom;
+import org.apache.skywalking.oap.server.core.storage.annotation.Column;
+
+/**
+ * Thermodynamic indicator represents the calculator for heat map.
+ *
+ * It groups the given collection of values by the given step and number of steps.
+ *
+ * A heat map (or heatmap) is a graphical representation of data where the individual values contained in a matrix are
+ * represented as colors.
+ *
+ * @author wusheng
+ */
+@IndicatorOperator
+public abstract class ThermodynamicIndicator extends Indicator {
+    protected static final String DETAIL_GROUP = "detail_group";
+    protected static final String STEP = "step";
+    protected static final String NUM_OF_STEPS = "num_of_steps";
+
+    @Getter @Setter @Column(columnName = STEP) private int step = 0;
+    @Getter @Setter @Column(columnName = NUM_OF_STEPS) private int numOfSteps = 0;
+    @Getter @Setter @Column(columnName = DETAIL_GROUP) private List<IntKeyLongValue> detailGroup = new ArrayList<>(30);
+
+    private Map<Integer, IntKeyLongValue> detailIndex;
+
+    /**
+     * Data will be grouped in
+     *
+     * [0, step), [step, step * 2), ..., [step * (maxNumOfSteps - 1), step * maxNumOfSteps), [step * maxNumOfSteps,
+     * MAX)
+     *
+     * @param value
+     * @param step the size of each step. A positive integer.
+     * @param maxNumOfSteps Steps are used to group incoming value.
+     */
+    @Entrance
+    public final void combine(@SourceFrom int value, @Arg int step, @Arg int maxNumOfSteps) {
+        if (this.step == 0) {
+            this.step = step;
+        }
+        if (this.numOfSteps == 0) {
+            this.numOfSteps = maxNumOfSteps + 1;
+        }
+
+        indexCheckAndInit();
+
+        int index = value / step;
+        if (index > maxNumOfSteps) {
+            index = numOfSteps;
+        }
+        IntKeyLongValue element = detailIndex.get(index);
+        if (element == null) {
+            element = new IntKeyLongValue();
+            element.setKey(index);
+            element.setValue(1);
+            addElement(element);
+        } else {
+            element.addValue(1);
+        }
+    }
+
+    @Override
+    public void combine(Indicator indicator) {
+        ThermodynamicIndicator thermodynamicIndicator = (ThermodynamicIndicator)indicator;
+        this.indexCheckAndInit();
+        thermodynamicIndicator.indexCheckAndInit();
+
+        thermodynamicIndicator.detailIndex.forEach((key, element) -> {
+            IntKeyLongValue existingElement = this.detailIndex.get(key);
+            if (existingElement == null) {
+                existingElement = new IntKeyLongValue();
+                existingElement.setKey(key);
+                existingElement.setValue(element.getValue());
+                addElement(element);
+            } else {
+                existingElement.addValue(element.getValue());
+            }
+        });
+    }
+
+    /**
+     * For Thermodynamic indicator, no single value field. Need to do nothing here.
+     */
+    @Override
+    public final void calculate() {
+
+    }
+
+    private void addElement(IntKeyLongValue element) {
+        detailGroup.add(element);
+        detailIndex.put(element.getKey(), element);
+    }
+
+    private void indexCheckAndInit() {
+        if (detailIndex == null) {
+            detailIndex = new HashMap<>();
+            detailGroup.forEach(element -> detailIndex.put(element.getKey(), element));
+        }
+    }
+}
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/indicator/ThermodynamicIndicatorTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/indicator/ThermodynamicIndicatorTest.java
new file mode 100644
index 0000000..3383b6b
--- /dev/null
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/indicator/ThermodynamicIndicatorTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.apache.skywalking.oap.server.core.analysis.indicator;
+
+import java.util.Map;
+import org.apache.skywalking.oap.server.core.remote.grpc.proto.RemoteData;
+import org.junit.Assert;
+import org.junit.Test;
+import org.powermock.reflect.Whitebox;
+
+/**
+ * @author wusheng
+ */
+public class ThermodynamicIndicatorTest {
+    private int step = 10;//ms
+    private int maxNumOfSteps = 10;//count
+
+    @Test
+    public void testEntrance() {
+        ThermodynamicIndicatorTest.ThermodynamicIndicatorMocker indicatorMocker = new ThermodynamicIndicatorTest.ThermodynamicIndicatorMocker();
+
+        indicatorMocker.combine(2000, step, maxNumOfSteps);
+        indicatorMocker.combine(110, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+        indicatorMocker.combine(50, step, maxNumOfSteps);
+        indicatorMocker.combine(50, step, maxNumOfSteps);
+        indicatorMocker.combine(28, step, maxNumOfSteps);
+        indicatorMocker.combine(50, step, maxNumOfSteps);
+        indicatorMocker.combine(61, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+
+        Map<Integer, IntKeyLongValue> index = Whitebox.getInternalState(indicatorMocker, "detailIndex");
+        Assert.assertEquals(5, index.size());
+
+        Assert.assertEquals(1, index.get(2).getValue());
+        Assert.assertEquals(3, index.get(5).getValue());
+        Assert.assertEquals(1, index.get(6).getValue());
+        Assert.assertEquals(6, index.get(10).getValue());
+        Assert.assertEquals(2, index.get(11).getValue());
+    }
+
+    @Test
+    public void testMerge() {
+        ThermodynamicIndicatorTest.ThermodynamicIndicatorMocker indicatorMocker = new ThermodynamicIndicatorTest.ThermodynamicIndicatorMocker();
+
+        indicatorMocker.combine(2000, step, maxNumOfSteps);
+        indicatorMocker.combine(110, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+        indicatorMocker.combine(100, step, maxNumOfSteps);
+        indicatorMocker.combine(50, step, maxNumOfSteps);
+        indicatorMocker.combine(50, step, maxNumOfSteps);
+
+        ThermodynamicIndicatorTest.ThermodynamicIndicatorMocker indicatorMocker2 = new ThermodynamicIndicatorTest.ThermodynamicIndicatorMocker();
+
+        indicatorMocker2.combine(28, step, maxNumOfSteps);
+        indicatorMocker2.combine(50, step, maxNumOfSteps);
+        indicatorMocker2.combine(61, step, maxNumOfSteps);
+        indicatorMocker2.combine(100, step, maxNumOfSteps);
+        indicatorMocker2.combine(100, step, maxNumOfSteps);
+        indicatorMocker2.combine(100, step, maxNumOfSteps);
+
+        indicatorMocker.combine(indicatorMocker2);
+
+        Map<Integer, IntKeyLongValue> index = Whitebox.getInternalState(indicatorMocker, "detailIndex");
+        Assert.assertEquals(5, index.size());
+
+        Assert.assertEquals(1, index.get(2).getValue());
+        Assert.assertEquals(3, index.get(5).getValue());
+        Assert.assertEquals(1, index.get(6).getValue());
+        Assert.assertEquals(6, index.get(10).getValue());
+        Assert.assertEquals(2, index.get(11).getValue());
+    }
+
+    public class ThermodynamicIndicatorMocker extends ThermodynamicIndicator {
+
+        @Override public String id() {
+            return null;
+        }
+
+        @Override public void deserialize(RemoteData remoteData) {
+
+        }
+
+        @Override public RemoteData.Builder serialize() {
+            return null;
+        }
+    }
+}