Add alarm metrics OP >= and <=, and refactor the operator logics (#4221)
* Add alarm metrics OP >= and <=, and refactor the operator logics * Add unit test for OP Co-authored-by: 吴晟 Wu Sheng <wu.sheng@foxmail.com>
This commit is contained in:
parent
1310719645
commit
094eeb870f
|
|
@ -17,7 +17,7 @@ endpoint name.
|
|||
For multiple values metrics, such as **percentile**, the threshold is an array. Described like `value1, value2, value3, value4, value5`.
|
||||
Each value could the threshold for each value of the metrics. Set the value to `-` if don't want to trigger alarm by this or some of the values.
|
||||
Such as in **percentile**, `value1` is threshold of P50, and `-, -, value3, value4, value5` means, there is no threshold for P50 and P75 in percentile alarm rule.
|
||||
- **OP**. Operator, support `>`, `<`, `=`. Welcome to contribute all OPs.
|
||||
- **OP**. Operator, support `>`, `>=`, `<`, `<=`, `=`. Welcome to contribute all OPs.
|
||||
- **Period**. How long should the alarm rule should be checked. This is a time window, which goes with the
|
||||
backend deployment env time.
|
||||
- **Count**. In the period window, if the number of **value**s over threshold(by OP), reaches count, alarm
|
||||
|
|
|
|||
|
|
@ -18,19 +18,62 @@
|
|||
|
||||
package org.apache.skywalking.oap.server.core.alarm.provider;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public enum OP {
|
||||
GREATER, LESS, EQUAL;
|
||||
GREATER {
|
||||
@Override
|
||||
public boolean test(final Number expected, final Number actual) {
|
||||
return requireNonNull(actual, "actual").doubleValue() > requireNonNull(expected, "expected").doubleValue();
|
||||
}
|
||||
},
|
||||
|
||||
GREATER_EQ {
|
||||
@Override
|
||||
public boolean test(final Number expected, final Number actual) {
|
||||
return requireNonNull(actual, "actual").doubleValue() >= requireNonNull(expected, "expected").doubleValue();
|
||||
}
|
||||
},
|
||||
|
||||
LESS {
|
||||
@Override
|
||||
public boolean test(final Number expected, final Number actual) {
|
||||
return requireNonNull(actual, "actual").doubleValue() < requireNonNull(expected, "expected").doubleValue();
|
||||
}
|
||||
},
|
||||
|
||||
LESS_EQ {
|
||||
@Override
|
||||
public boolean test(final Number expected, final Number actual) {
|
||||
return requireNonNull(actual, "actual").doubleValue() <= requireNonNull(expected, "expected").doubleValue();
|
||||
}
|
||||
},
|
||||
|
||||
// NOTICE: double equal is not reliable in Java,
|
||||
// match result is not predictable
|
||||
EQUAL {
|
||||
@Override
|
||||
public boolean test(final Number expected, final Number actual) {
|
||||
return requireNonNull(actual, "actual").doubleValue() == requireNonNull(expected, "expected").doubleValue();
|
||||
}
|
||||
};
|
||||
|
||||
public static OP get(String op) {
|
||||
switch (op) {
|
||||
case ">":
|
||||
return GREATER;
|
||||
case ">=":
|
||||
return GREATER_EQ;
|
||||
case "<":
|
||||
return LESS;
|
||||
case "<=":
|
||||
return LESS_EQ;
|
||||
case "==":
|
||||
return EQUAL;
|
||||
default:
|
||||
throw new IllegalArgumentException("unknown op, " + op);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean test(final Number expected, final Number actual);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -292,63 +292,27 @@ public class RunningRule {
|
|||
case LONG:
|
||||
long lvalue = ((LongValueHolder)metrics).getValue();
|
||||
long lexpected = RunningRule.this.threshold.getLongThreshold();
|
||||
switch (op) {
|
||||
case GREATER:
|
||||
if (lvalue > lexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
case LESS:
|
||||
if (lvalue < lexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
case EQUAL:
|
||||
if (lvalue == lexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
if (op.test(lexpected, lvalue)) {
|
||||
matchCount++;
|
||||
}
|
||||
break;
|
||||
case INT:
|
||||
int ivalue = ((IntValueHolder)metrics).getValue();
|
||||
int iexpected = RunningRule.this.threshold.getIntThreshold();
|
||||
switch (op) {
|
||||
case LESS:
|
||||
if (ivalue < iexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
case GREATER:
|
||||
if (ivalue > iexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
case EQUAL:
|
||||
if (ivalue == iexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
if (op.test(iexpected, ivalue)) {
|
||||
matchCount++;
|
||||
}
|
||||
break;
|
||||
case DOUBLE:
|
||||
double dvalue = ((DoubleValueHolder)metrics).getValue();
|
||||
double dexpected = RunningRule.this.threshold.getDoubleThreshold();
|
||||
switch (op) {
|
||||
case EQUAL:
|
||||
// NOTICE: double equal is not reliable in Java,
|
||||
// match result is not predictable
|
||||
if (dvalue == dexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
case GREATER:
|
||||
if (dvalue > dexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
case LESS:
|
||||
if (dvalue < dexpected)
|
||||
matchCount++;
|
||||
break;
|
||||
if (op.test(dexpected, dvalue)) {
|
||||
matchCount++;
|
||||
}
|
||||
break;
|
||||
case MULTI_INTS:
|
||||
int[] ivalueArray = ((MultiIntValuesHolder)metrics).getValues();
|
||||
Integer[] iaexpected = RunningRule.this.threshold.getIntValuesThreshold();
|
||||
MULTI_VALUE_CHECK:
|
||||
for (int i = 0; i < ivalueArray.length; i++) {
|
||||
ivalue = ivalueArray[i];
|
||||
Integer iNullableExpected = 0;
|
||||
|
|
@ -358,25 +322,9 @@ public class RunningRule {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
switch (op) {
|
||||
case LESS:
|
||||
if (ivalue < iNullableExpected) {
|
||||
matchCount++;
|
||||
break MULTI_VALUE_CHECK;
|
||||
}
|
||||
break;
|
||||
case GREATER:
|
||||
if (ivalue > iNullableExpected) {
|
||||
matchCount++;
|
||||
break MULTI_VALUE_CHECK;
|
||||
}
|
||||
break;
|
||||
case EQUAL:
|
||||
if (ivalue == iNullableExpected) {
|
||||
matchCount++;
|
||||
break MULTI_VALUE_CHECK;
|
||||
}
|
||||
break;
|
||||
if (op.test(iNullableExpected, ivalue)) {
|
||||
matchCount++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.alarm.provider;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class OPTest {
|
||||
@Test
|
||||
public void test() {
|
||||
assertTrue(OP.EQUAL.test(123, 123));
|
||||
assertTrue(OP.EQUAL.test(123L, 123L));
|
||||
assertTrue(OP.EQUAL.test(123.0D, 123.0D));
|
||||
|
||||
assertTrue(OP.GREATER.test(122, 123));
|
||||
assertTrue(OP.GREATER.test(122L, 123L));
|
||||
assertTrue(OP.GREATER.test(122.0D, 123.0D));
|
||||
|
||||
assertTrue(OP.GREATER_EQ.test(122, 123));
|
||||
assertTrue(OP.GREATER_EQ.test(122L, 123L));
|
||||
assertTrue(OP.GREATER_EQ.test(122.0D, 123.0D));
|
||||
|
||||
assertTrue(OP.LESS.test(124, 123));
|
||||
assertTrue(OP.LESS.test(124L, 123L));
|
||||
assertTrue(OP.LESS.test(124.0D, 123.0D));
|
||||
}
|
||||
}
|
||||
|
|
@ -89,11 +89,10 @@ public abstract class PercentileMetrics extends GroupMetrics implements MultiInt
|
|||
}
|
||||
|
||||
int count = 0;
|
||||
IntKeyLongValue[] sortedData = dataset.values().stream().sorted(new Comparator<IntKeyLongValue>() {
|
||||
@Override public int compare(IntKeyLongValue o1, IntKeyLongValue o2) {
|
||||
return o1.getKey() - o2.getKey();
|
||||
}
|
||||
}).toArray(IntKeyLongValue[]::new);
|
||||
IntKeyLongValue[] sortedData = dataset.values()
|
||||
.stream()
|
||||
.sorted(Comparator.comparingInt(IntKeyLongValue::getKey))
|
||||
.toArray(IntKeyLongValue[]::new);
|
||||
for (IntKeyLongValue element : sortedData) {
|
||||
count += element.getValue();
|
||||
for (int i = index; i < roofs.length; i++) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue