This is an automated email from the ASF dual-hosted git repository. ningjiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit 37a2d03a0c523b3dd7c65bbebff6d0e39973dd5d Author: zhengyangyong <[email protected]> AuthorDate: Thu Jan 11 14:14:09 2018 +0800 SCB-150 add success/failed dimension for call count and tps Signed-off-by: zhengyangyong <[email protected]> --- metrics/metrics-common/pom.xml | 4 +- .../metrics/common/DoubleMetricValue.java | 60 ++++++++++++++++++++ .../metrics/common/LongMetricValue.java | 60 ++++++++++++++++++++ .../io/servicecomb/metrics/common/MetricValue.java | 65 ++++++++++++++++++++++ .../servicecomb/metrics/common/CallMetric.java | 37 +++++++----- .../servicecomb/metrics/core/MetricsDimension.java | 39 +++++++++++++ .../metrics/core/monitor/CallMonitor.java | 65 ++++++++++++++++++---- 7 files changed, 304 insertions(+), 26 deletions(-) diff --git a/metrics/metrics-common/pom.xml b/metrics/metrics-common/pom.xml index 21dddbd..5987595 100644 --- a/metrics/metrics-common/pom.xml +++ b/metrics/metrics-common/pom.xml @@ -31,8 +31,8 @@ <dependencies> <dependency> - <groupId>com.fasterxml.jackson.core</groupId> - <artifactId>jackson-databind</artifactId> + <groupId>io.servicecomb</groupId> + <artifactId>foundation-common</artifactId> </dependency> </dependencies> diff --git a/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/DoubleMetricValue.java b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/DoubleMetricValue.java new file mode 100644 index 0000000..c116562 --- /dev/null +++ b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/DoubleMetricValue.java @@ -0,0 +1,60 @@ +/* + * 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 io.servicecomb.metrics.common; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import io.servicecomb.foundation.common.exceptions.ServiceCombException; + +public class DoubleMetricValue extends MetricValue<Double> { + public DoubleMetricValue(Double value, Map<String, String> dimensions) { + super(value, dimensions); + } + + public DoubleMetricValue(@JsonProperty("key") String key, + @JsonProperty("value") Double value, + @JsonProperty("dimensions") Map<String, String> dimensions) { + super(key, value, dimensions); + } + + public DoubleMetricValue merge(DoubleMetricValue value) { + if (this.getKey().equals(value.getKey())) { + return new DoubleMetricValue(this.getKey(), this.getValue() + value.getValue(), this.getDimensions()); + } + throw new ServiceCombException("unable merge different key values,source key :" + value.getKey() + + " target key :" + this.getKey()); + } + + public static List<DoubleMetricValue> merge(List<DoubleMetricValue> source, List<DoubleMetricValue> target) { + Map<String, DoubleMetricValue> finalValues = new HashMap<>(); + for (DoubleMetricValue t : target) { + finalValues.put(t.getKey(), t); + } + for (DoubleMetricValue s : source) { + if (finalValues.containsKey(s.getKey())) { + finalValues.put(s.getKey(), finalValues.get(s.getKey()).merge(s)); + } + } + return new ArrayList<>(finalValues.values()); + } +} diff --git a/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/LongMetricValue.java b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/LongMetricValue.java new file mode 100644 index 0000000..eb0ac8d --- /dev/null +++ b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/LongMetricValue.java @@ -0,0 +1,60 @@ +/* + * 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 io.servicecomb.metrics.common; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import io.servicecomb.foundation.common.exceptions.ServiceCombException; + +public class LongMetricValue extends MetricValue<Long> { + public LongMetricValue(Long value, Map<String, String> dimensions) { + super(value, dimensions); + } + + public LongMetricValue(@JsonProperty("key") String key, + @JsonProperty("value") Long value, + @JsonProperty("dimensions") Map<String, String> dimensions) { + super(key, value, dimensions); + } + + public LongMetricValue merge(LongMetricValue value) { + if (this.getKey().equals(value.getKey())) { + return new LongMetricValue(this.getKey(), this.getValue() + value.getValue(), this.getDimensions()); + } + throw new ServiceCombException("unable merge different key values,source key :" + value.getKey() + + " target key :" + this.getKey()); + } + + public static List<LongMetricValue> merge(List<LongMetricValue> source, List<LongMetricValue> target) { + Map<String, LongMetricValue> finalValues = new HashMap<>(); + for (LongMetricValue t : target) { + finalValues.put(t.getKey(), t); + } + for (LongMetricValue s : source) { + if (finalValues.containsKey(s.getKey())) { + finalValues.put(s.getKey(), finalValues.get(s.getKey()).merge(s)); + } + } + return new ArrayList<>(finalValues.values()); + } +} diff --git a/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/MetricValue.java b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/MetricValue.java new file mode 100644 index 0000000..c368aba --- /dev/null +++ b/metrics/metrics-common/src/main/java/io/servicecomb/metrics/common/MetricValue.java @@ -0,0 +1,65 @@ +/* + * 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 io.servicecomb.metrics.common; + +import java.util.Arrays; +import java.util.Map; + +public class MetricValue<T extends Number> { + private final String key; + + private final T value; + + private final Map<String, String> dimensions; + + public String getKey() { + return key; + } + + public T getValue() { + return value; + } + + public Map<String, String> getDimensions() { + return dimensions; + } + + public MetricValue(T value, Map<String, String> dimensions) { + String finalKey = "{}"; + if (dimensions != null && dimensions.size() != 0) { + String[] keys = dimensions.keySet().toArray(new String[0]); + Arrays.sort(keys); + StringBuilder builder = new StringBuilder("{"); + for (String key : keys) { + builder.append(String.format("%s=%s,", key, dimensions.get(key))); + } + builder.deleteCharAt(dimensions.size() - 1); + builder.append("}"); + finalKey = builder.toString(); + } + this.key = finalKey; + this.value = value; + this.dimensions = dimensions; + } + + public MetricValue(String key, T value, Map<String, String> dimensions) { + this.key = key; + this.value = value; + this.dimensions = dimensions; + } +} diff --git a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java index 5e0d63b..a65ee92 100644 --- a/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java +++ b/metrics/metrics-common/src/main/java/org/apache/servicecomb/metrics/common/CallMetric.java @@ -17,7 +17,9 @@ package org.apache.servicecomb.metrics.common; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.fasterxml.jackson.annotation.JsonProperty; @@ -25,37 +27,44 @@ import com.fasterxml.jackson.annotation.JsonProperty; public class CallMetric { private final String prefix; - private final long total; + private final List<LongMetricValue> totalValues; - private final double tps; + private final List<DoubleMetricValue> tpsValues; - public long getTotal() { - return total; + public List<LongMetricValue> getTotalValues() { + return totalValues; } - public double getTps() { - return tps; + public List<DoubleMetricValue> getTpsValues() { + return tpsValues; } public CallMetric(String prefix) { - this(prefix, 0, 0); + this(prefix, new ArrayList<>(), new ArrayList<>()); } - public CallMetric(@JsonProperty("prefix") String prefix, @JsonProperty("total") long total, - @JsonProperty("tps") double tps) { + public CallMetric(@JsonProperty("prefix") String prefix, + @JsonProperty("totalValues") List<LongMetricValue> totalValues, + @JsonProperty("tpsValues") List<DoubleMetricValue> tpsValues) { this.prefix = prefix; - this.total = total; - this.tps = tps; + this.totalValues = totalValues; + this.tpsValues = tpsValues; } public CallMetric merge(CallMetric metric) { - return new CallMetric(this.prefix, this.total + metric.total, this.tps + metric.tps); + return new CallMetric(this.prefix, + LongMetricValue.merge(metric.getTotalValues(), this.getTotalValues()), + DoubleMetricValue.merge(metric.getTpsValues(), this.getTpsValues())); } public Map<String, Number> toMap() { Map<String, Number> metrics = new HashMap<>(); - metrics.put(prefix + ".total", total); - metrics.put(prefix + ".tps", tps); + for (MetricValue totalValue : totalValues) { + metrics.put(prefix + ".total." + totalValue.getKey(), totalValue.getValue()); + } + for (MetricValue tpsValue : tpsValues) { + metrics.put(prefix + ".tps." + tpsValue.getKey(), tpsValue.getValue()); + } return metrics; } } diff --git a/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/MetricsDimension.java b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/MetricsDimension.java new file mode 100644 index 0000000..bf9170f --- /dev/null +++ b/metrics/metrics-core/src/main/java/io/servicecomb/metrics/core/MetricsDimension.java @@ -0,0 +1,39 @@ +/* + * 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 io.servicecomb.metrics.core; + +import io.servicecomb.foundation.common.exceptions.ServiceCombException; + +public class MetricsDimension { + public static final String DIMENSION_STATUS = "Status"; + + public static final String DIMENSION_STATUS_ALL = "all"; + + public static final String DIMENSION_STATUS_SUCCESS = "success"; + + public static final String DIMENSION_STATUS_FAILED = "failed"; + + public static String[] getDimensionOptions(String dimension) { + if (DIMENSION_STATUS.equals(dimension)) { + return new String[] {MetricsDimension.DIMENSION_STATUS_ALL, + MetricsDimension.DIMENSION_STATUS_SUCCESS, + MetricsDimension.DIMENSION_STATUS_FAILED}; + } + throw new ServiceCombException("illegal dimension key : " + dimension); + } +} diff --git a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java index 1e68201..7174e33 100644 --- a/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java +++ b/metrics/metrics-core/src/main/java/org/apache/servicecomb/metrics/core/monitor/CallMonitor.java @@ -19,37 +19,82 @@ package org.apache.servicecomb.metrics.core.monitor; import org.apache.servicecomb.metrics.common.CallMetric; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import com.netflix.servo.monitor.BasicCounter; import com.netflix.servo.monitor.MonitorConfig; import com.netflix.servo.monitor.StepCounter; +import com.netflix.servo.tag.Tag; +import com.netflix.servo.tag.TagList; + +import io.servicecomb.metrics.common.CallMetric; +import io.servicecomb.metrics.common.DoubleMetricValue; +import io.servicecomb.metrics.common.LongMetricValue; +import io.servicecomb.metrics.core.MetricsDimension; public class CallMonitor { private final String prefix; - private final BasicCounter total; + private final List<BasicCounter> totalCounters; - private final StepCounter tps; + private final List<StepCounter> tpsCounters; - public CallMonitor(String prefix) { + public CallMonitor(String prefix, String... dimensions) { this.prefix = prefix; - this.total = new BasicCounter(MonitorConfig.builder(prefix + ".total").build()); - this.tps = new StepCounter(MonitorConfig.builder(prefix + ".tps").build()); + this.totalCounters = new ArrayList<>(); + this.tpsCounters = new ArrayList<>(); + if (dimensions.length == 0) { + this.totalCounters.add(new BasicCounter(MonitorConfig.builder(prefix + ".total").build())); + this.tpsCounters.add(new StepCounter(MonitorConfig.builder(prefix + ".tps").build())); + } else { + for (String dimension : dimensions) { + for (String option : MetricsDimension.getDimensionOptions(dimension)) { + this.totalCounters + .add(new BasicCounter(MonitorConfig.builder(prefix + ".total").withTag(dimension, option).build())); + this.tpsCounters + .add(new StepCounter(MonitorConfig.builder(prefix + ".tps").withTag(dimension, option).build())); + } + } + } } public void increment() { - total.increment(); - tps.increment(); + for (int i = 0; i < totalCounters.size(); i++) { + totalCounters.get(i).increment(); + tpsCounters.get(i).increment(); + } } public CallMetric toMetric(int windowTimeIndex) { - return new CallMetric(this.prefix, total.getValue(windowTimeIndex).longValue(), - this.adjustValue(tps.getValue(windowTimeIndex).doubleValue())); + List<LongMetricValue> totalValues = new ArrayList<>(); + List<DoubleMetricValue> tpsValues = new ArrayList<>(); + for (int i = 0; i < totalCounters.size(); i++) { + totalValues.add(new LongMetricValue(totalCounters.get(i).getValue(windowTimeIndex).longValue(), + convertTags(totalCounters.get(i).getConfig().getTags()))); + tpsValues.add(new DoubleMetricValue(adjustValue(tpsCounters.get(i).getValue(windowTimeIndex).doubleValue()), + convertTags(tpsCounters.get(i).getConfig().getTags()))); + } + return new CallMetric(this.prefix, totalValues, tpsValues); } //for time-related monitor type, if stop poll value over one window time, //the value may return -1 because servo can't known precise value of previous step //so must change to return 0 - public double adjustValue(double value) { + private double adjustValue(double value) { return value < 0 ? 0 : value; } + + private Map<String, String> convertTags(TagList tags) { + if (tags.size() != 0) { + Map<String, String> tagMap = new HashMap<>(); + for (Tag tag : tags) { + tagMap.put(tag.getKey(), tag.getValue()); + } + return tagMap; + } + return null; + } } -- To stop receiving notification emails like this one, please contact [email protected].
