Add metrics provider/consumer uts (#12120)
* Provide uts in metrics-api * Provide uts in metrics-default * Provide uts in metrics-default * Update pom.xml * Update pom.xml * Remove 'import *' * Remove 'import *' * Merge remote branch * Add license * Update DefaultDubboClientObservationConventionTest.java * Merge remote branch * Add ut for METRIC_QPS * Add ut for Provider/Consumer Metrics * Add ut for Provider/Consumer Metrics * Add ut for Provider/Consumer Metrics * Update pom.xml for test * Add test for p95 & p99 * Add test for p95 & p99 * Update pom.xml * Update import * Remove unused todo * Update test * Remove unused import * Remove unnecessary test unit * Fix codestyle problems * Fix codestyle problems
This commit is contained in:
parent
1b838281a4
commit
742e035a8a
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.dubbo.common.utils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* A utility class that provides methods for accessing and manipulating private fields and methods of an object.
|
||||
* This is useful for white-box testing, where the internal workings of a class need to be tested directly.
|
||||
* <p>
|
||||
* Note: Usage of this class should be limited to testing purposes only, as it violates the encapsulation principle.
|
||||
*/
|
||||
public class ReflectionUtils {
|
||||
|
||||
private ReflectionUtils(){}
|
||||
|
||||
/**
|
||||
* Retrieves the value of the specified field from the given object.
|
||||
*
|
||||
* @param source The object from which to retrieve the field value.
|
||||
* @param fieldName The name of the field to retrieve.
|
||||
* @return The value of the specified field in the given object.
|
||||
* @throws RuntimeException If the specified field does not exist.
|
||||
*/
|
||||
public static Object getField(Object source, String fieldName) {
|
||||
try {
|
||||
Field f = source.getClass().getDeclaredField(fieldName);
|
||||
f.setAccessible(true);
|
||||
return f.get(source);
|
||||
} catch (Exception e) {
|
||||
throw new ReflectionException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the specified method on the given object with the provided parameters.
|
||||
*
|
||||
* @param source The object on which to invoke the method.
|
||||
* @param methodName The name of the method to invoke.
|
||||
* @param params The parameters to pass to the method.
|
||||
* @return The result of invoking the specified method on the given object.
|
||||
*/
|
||||
public static Object invoke(Object source, String methodName, Object... params) {
|
||||
try {
|
||||
Class<?>[] classes = Arrays.stream(params)
|
||||
.map(param -> param != null ? param.getClass() : null)
|
||||
.toArray(Class<?>[]::new);
|
||||
|
||||
for (Method method : source.getClass().getDeclaredMethods()) {
|
||||
if (method.getName().equals(methodName) && matchParameters(method.getParameterTypes(), classes)) {
|
||||
method.setAccessible(true);
|
||||
return method.invoke(source, params);
|
||||
}
|
||||
}
|
||||
throw new NoSuchMethodException("No method found with the specified name and parameter types");
|
||||
} catch (Exception e) {
|
||||
throw new ReflectionException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean matchParameters(Class<?>[] methodParamTypes, Class<?>[] givenParamTypes) {
|
||||
if (methodParamTypes.length != givenParamTypes.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < methodParamTypes.length; i++) {
|
||||
if (givenParamTypes[i] == null) {
|
||||
if (methodParamTypes[i].isPrimitive()) {
|
||||
return false;
|
||||
}
|
||||
} else if (!methodParamTypes[i].isAssignableFrom(givenParamTypes[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class ReflectionException extends RuntimeException{
|
||||
public ReflectionException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.apache.dubbo.metrics.observation.utils.ObservationConventionUtils;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
||||
public class DefaultDubboClientObservationConventionTest {
|
||||
|
||||
static DubboClientObservationConvention dubboClientObservationConvention = DefaultDubboClientObservationConvention.getInstance();
|
||||
|
||||
@Test
|
||||
void testGetName() {
|
||||
Assertions.assertEquals("rpc.client.duration", dubboClientObservationConvention.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetLowCardinalityKeyValues() throws NoSuchFieldException, IllegalAccessException {
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
invocation.setMethodName("testMethod");
|
||||
invocation.setAttachment("interface", "com.example.TestService");
|
||||
invocation.setTargetServiceUniqueName("targetServiceName1");
|
||||
|
||||
Invoker<?> invoker = ObservationConventionUtils.getMockInvokerWithUrl();
|
||||
invocation.setInvoker(invoker);
|
||||
|
||||
DubboClientContext context = new DubboClientContext(invoker, invocation);
|
||||
|
||||
KeyValues keyValues = dubboClientObservationConvention.getLowCardinalityKeyValues(context);
|
||||
|
||||
Assertions.assertEquals("testMethod", ObservationConventionUtils.getValueForKey(keyValues, "rpc.method"));
|
||||
Assertions.assertEquals("targetServiceName1", ObservationConventionUtils.getValueForKey(keyValues, "rpc.service"));
|
||||
Assertions.assertEquals("apache_dubbo", ObservationConventionUtils.getValueForKey(keyValues, "rpc.system"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetContextualName() {
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
Invoker<?> invoker = ObservationConventionUtils.getMockInvokerWithUrl();
|
||||
invocation.setMethodName("testMethod");
|
||||
invocation.setServiceName("com.example.TestService");
|
||||
|
||||
DubboClientContext context = new DubboClientContext(invoker, invocation);
|
||||
|
||||
DefaultDubboClientObservationConvention convention = new DefaultDubboClientObservationConvention();
|
||||
|
||||
String contextualName = convention.getContextualName(context);
|
||||
Assertions.assertEquals("com.example.TestService/testMethod", contextualName);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.dubbo.metrics.observation;
|
||||
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.apache.dubbo.metrics.observation.utils.ObservationConventionUtils;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class DefaultDubboServerObservationConventionTest {
|
||||
|
||||
static DubboServerObservationConvention dubboServerObservationConvention = DefaultDubboServerObservationConvention.getInstance();
|
||||
|
||||
@Test
|
||||
void testGetName() {
|
||||
Assertions.assertEquals("rpc.server.duration", dubboServerObservationConvention.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetLowCardinalityKeyValues() throws NoSuchFieldException, IllegalAccessException {
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
invocation.setMethodName("testMethod");
|
||||
invocation.setAttachment("interface", "com.example.TestService");
|
||||
invocation.setTargetServiceUniqueName("targetServiceName1");
|
||||
|
||||
Invoker<?> invoker = ObservationConventionUtils.getMockInvokerWithUrl();
|
||||
invocation.setInvoker(invoker);
|
||||
|
||||
DubboServerContext context = new DubboServerContext(invoker, invocation);
|
||||
|
||||
KeyValues keyValues = dubboServerObservationConvention.getLowCardinalityKeyValues(context);
|
||||
|
||||
Assertions.assertEquals("testMethod", ObservationConventionUtils.getValueForKey(keyValues, "rpc.method"));
|
||||
Assertions.assertEquals("targetServiceName1", ObservationConventionUtils.getValueForKey(keyValues, "rpc.service"));
|
||||
Assertions.assertEquals("apache_dubbo", ObservationConventionUtils.getValueForKey(keyValues, "rpc.system"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetContextualName() {
|
||||
RpcInvocation invocation = new RpcInvocation();
|
||||
Invoker<?> invoker = ObservationConventionUtils.getMockInvokerWithUrl();
|
||||
invocation.setMethodName("testMethod");
|
||||
invocation.setServiceName("com.example.TestService");
|
||||
|
||||
DubboClientContext context = new DubboClientContext(invoker, invocation);
|
||||
|
||||
DefaultDubboClientObservationConvention convention = new DefaultDubboClientObservationConvention();
|
||||
|
||||
String contextualName = convention.getContextualName(context);
|
||||
Assertions.assertEquals("com.example.TestService/testMethod", contextualName);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.dubbo.metrics.observation.utils;
|
||||
|
||||
import io.micrometer.common.KeyValue;
|
||||
import io.micrometer.common.KeyValues;
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.rpc.Invoker;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class ObservationConventionUtils {
|
||||
|
||||
|
||||
public static Invoker<?> getMockInvokerWithUrl(){
|
||||
URL url = URL.valueOf("dubbo://127.0.0.1:12345/com.example.TestService?anyhost=true&application=test&category=providers&dubbo=2.0.2&generic=false&interface=com.example.TestService&methods=testMethod&pid=26716&side=provider×tamp=1633863896653");
|
||||
Invoker<?> invoker = Mockito.mock(Invoker.class);
|
||||
Mockito.when(invoker.getUrl()).thenReturn(url);
|
||||
return invoker;
|
||||
}
|
||||
|
||||
public static String getValueForKey(KeyValues keyValues, Object key) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field f = KeyValues.class.getDeclaredField("keyValues");
|
||||
f.setAccessible(true);
|
||||
KeyValue[] kv = (KeyValue[]) f.get(keyValues);
|
||||
for (KeyValue keyValue : kv) {
|
||||
if (keyValue.getKey().equals(key)) {
|
||||
return keyValue.getValue();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -46,6 +46,5 @@
|
|||
<artifactId>micrometer-tracing-integration-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.dubbo.metrics;
|
||||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.metrics.collector.MetricsCollector;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.metrics.service.DefaultMetricsService;
|
||||
import org.apache.dubbo.metrics.service.MetricsEntity;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class DefaultMetricsServiceTest {
|
||||
|
||||
private MetricsCollector metricsCollector;
|
||||
|
||||
private DefaultMetricsService defaultMetricsService;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
ApplicationModel applicationModel = Mockito.mock(ApplicationModel.class);
|
||||
ScopeBeanFactory beanFactory = Mockito.mock(ScopeBeanFactory.class);
|
||||
metricsCollector = Mockito.mock(MetricsCollector.class);
|
||||
|
||||
when(applicationModel.getBeanFactory()).thenReturn(beanFactory);
|
||||
when(beanFactory.getBeansOfType(MetricsCollector.class)).thenReturn(Collections.singletonList(metricsCollector));
|
||||
|
||||
defaultMetricsService = new DefaultMetricsService(applicationModel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMetricsByCategories() {
|
||||
MetricSample sample = new GaugeMetricSample<>(
|
||||
"testMetric",
|
||||
"testDescription",
|
||||
null,
|
||||
MetricsCategory.REQUESTS,
|
||||
42,
|
||||
value -> 42.0
|
||||
);
|
||||
when(metricsCollector.collect()).thenReturn(Collections.singletonList(sample));
|
||||
List<MetricsCategory> categories = Collections.singletonList(MetricsCategory.REQUESTS);
|
||||
|
||||
Map<MetricsCategory, List<MetricsEntity>> result = defaultMetricsService.getMetricsByCategories(categories);
|
||||
|
||||
Assertions.assertNotNull(result);
|
||||
Assertions.assertEquals(1, result.size());
|
||||
List<MetricsEntity> entities = result.get(MetricsCategory.REQUESTS);
|
||||
Assertions.assertNotNull(entities);
|
||||
Assertions.assertEquals(1, entities.size());
|
||||
|
||||
MetricsEntity entity = entities.get(0);
|
||||
Assertions.assertEquals("testMetric", entity.getName());
|
||||
Assertions.assertEquals(42.0, entity.getValue());
|
||||
Assertions.assertEquals(MetricsCategory.REQUESTS, entity.getCategory());
|
||||
}
|
||||
}
|
||||
|
|
@ -18,40 +18,53 @@
|
|||
package org.apache.dubbo.metrics.collector;
|
||||
|
||||
import org.apache.dubbo.common.URL;
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.common.constants.CommonConstants;
|
||||
import org.apache.dubbo.common.utils.ReflectionUtils;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
|
||||
import org.apache.dubbo.config.MetricsConfig;
|
||||
|
||||
import org.apache.dubbo.config.context.ConfigManager;
|
||||
import org.apache.dubbo.config.nested.AggregationConfig;
|
||||
import org.apache.dubbo.metrics.TestMetricsInvoker;
|
||||
import org.apache.dubbo.metrics.aggregate.TimeWindowCounter;
|
||||
import org.apache.dubbo.metrics.collector.sample.MethodMetricsSampler;
|
||||
import org.apache.dubbo.metrics.event.MetricsEvent;
|
||||
import org.apache.dubbo.metrics.event.RTEvent;
|
||||
import org.apache.dubbo.metrics.model.MethodMetric;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.rpc.RpcContext;
|
||||
import org.apache.dubbo.rpc.RpcInvocation;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.*;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.*;
|
||||
import static org.apache.dubbo.metrics.model.MetricsCategory.QPS;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
class AggregateMetricsCollectorTest {
|
||||
|
||||
private ApplicationModel applicationModel;
|
||||
private DefaultMetricsCollector defaultCollector;
|
||||
|
||||
private String interfaceName;
|
||||
private String methodName;
|
||||
private String group;
|
||||
|
|
@ -59,6 +72,37 @@ class AggregateMetricsCollectorTest {
|
|||
private RpcInvocation invocation;
|
||||
private String side;
|
||||
|
||||
public static MethodMetric getTestMethodMetric() {
|
||||
|
||||
MethodMetric methodMetric = new MethodMetric();
|
||||
methodMetric.setApplicationName("TestApp");
|
||||
methodMetric.setInterfaceName("TestInterface");
|
||||
methodMetric.setMethodName("TestMethod");
|
||||
methodMetric.setGroup("TestGroup");
|
||||
methodMetric.setVersion("1.0.0");
|
||||
methodMetric.setSide("PROVIDER");
|
||||
|
||||
return methodMetric;
|
||||
}
|
||||
|
||||
public static AggregateMetricsCollector getTestCollector() {
|
||||
|
||||
ApplicationModel applicationModel = mock(ApplicationModel.class);
|
||||
ConfigManager configManager = new ConfigManager(applicationModel);
|
||||
MetricsConfig metricsConfig = spy(new MetricsConfig());
|
||||
|
||||
configManager.setMetrics(metricsConfig);
|
||||
|
||||
when(metricsConfig.getAggregation()).thenReturn(new AggregationConfig());
|
||||
when(applicationModel.getApplicationConfigManager()).thenReturn(configManager);
|
||||
|
||||
ScopeBeanFactory beanFactory = mock(ScopeBeanFactory.class);
|
||||
when(beanFactory.getBean(DefaultMetricsCollector.class)).thenReturn(new DefaultMetricsCollector());
|
||||
when(applicationModel.getBeanFactory()).thenReturn(beanFactory);
|
||||
|
||||
return new AggregateMetricsCollector(applicationModel);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
ApplicationConfig config = new ApplicationConfig();
|
||||
|
|
@ -167,4 +211,97 @@ class AggregateMetricsCollectorTest {
|
|||
Assertions.assertTrue(sampleMap.containsKey(MetricsKey.METRIC_RT_P99.getNameByType(side)));
|
||||
Assertions.assertTrue(sampleMap.containsKey(MetricsKey.METRIC_RT_P95.getNameByType(side)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQPS() {
|
||||
ApplicationModel applicationModel = mock(ApplicationModel.class);
|
||||
ConfigManager configManager = mock(ConfigManager.class);
|
||||
MetricsConfig metricsConfig = mock(MetricsConfig.class);
|
||||
ScopeBeanFactory beanFactory = mock(ScopeBeanFactory.class);
|
||||
AggregationConfig aggregationConfig = mock(AggregationConfig.class);
|
||||
|
||||
when(applicationModel.getApplicationConfigManager()).thenReturn(configManager);
|
||||
when(applicationModel.getBeanFactory()).thenReturn(beanFactory);
|
||||
when(beanFactory.getBean(DefaultMetricsCollector.class)).thenReturn(new DefaultMetricsCollector());
|
||||
when(configManager.getMetrics()).thenReturn(Optional.of(metricsConfig));
|
||||
when(metricsConfig.getAggregation()).thenReturn(aggregationConfig);
|
||||
when(aggregationConfig.getEnabled()).thenReturn(Boolean.TRUE);
|
||||
|
||||
AggregateMetricsCollector collector = new AggregateMetricsCollector(applicationModel);
|
||||
|
||||
MethodMetric methodMetric = getTestMethodMetric();
|
||||
|
||||
TimeWindowCounter qpsCounter = new TimeWindowCounter(10, 120);
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
qpsCounter.increment();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ConcurrentHashMap<MethodMetric, TimeWindowCounter> qps = (ConcurrentHashMap<MethodMetric, TimeWindowCounter>) ReflectionUtils.getField(collector, "qps");
|
||||
qps.put(methodMetric, qpsCounter);
|
||||
|
||||
List<MetricSample> collectedQPS = new ArrayList<>();
|
||||
ReflectionUtils.invoke(collector, "collectQPS", collectedQPS);
|
||||
|
||||
Assertions.assertFalse(collectedQPS.isEmpty());
|
||||
Assertions.assertEquals(1, collectedQPS.size());
|
||||
|
||||
MetricSample sample = collectedQPS.get(0);
|
||||
Assertions.assertEquals(MetricsKey.METRIC_QPS.getNameByType("PROVIDER"), sample.getName());
|
||||
Assertions.assertEquals(MetricsKey.METRIC_QPS.getDescription(), sample.getDescription());
|
||||
|
||||
Assertions.assertEquals(QPS, sample.getCategory());
|
||||
Assertions.assertEquals(10000, ((TimeWindowCounter) ((GaugeMetricSample<?>) sample).getValue()).get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testP95AndP99() throws InterruptedException {
|
||||
AggregateMetricsCollector collector = getTestCollector();
|
||||
MethodMetric methodMetric = getTestMethodMetric();
|
||||
|
||||
List<Double> requestTimes = new ArrayList<>(10000);
|
||||
|
||||
for (int i = 0; i < 300; i++) {
|
||||
requestTimes.add(1000 * Math.random());
|
||||
}
|
||||
|
||||
Collections.sort(requestTimes);
|
||||
double p95Index = 0.95 * (requestTimes.size() - 1);
|
||||
double p99Index = 0.99 * (requestTimes.size() - 1);
|
||||
|
||||
double manualP95 = requestTimes.get((int) Math.round(p95Index));
|
||||
double manualP99 = requestTimes.get((int) Math.round(p99Index));
|
||||
|
||||
for (Double requestTime : requestTimes) {
|
||||
collector.onEvent(new RTEvent(applicationModel, methodMetric, requestTime.longValue()));
|
||||
}
|
||||
Thread.sleep(4000L);
|
||||
|
||||
List<MetricSample> samples = collector.collect();
|
||||
|
||||
GaugeMetricSample<?> p95Sample = samples.stream()
|
||||
.filter(sample -> sample.getName().endsWith("p95"))
|
||||
.map(sample -> (GaugeMetricSample<?>) sample)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
GaugeMetricSample<?> p99Sample = samples.stream()
|
||||
.filter(sample -> sample.getName().endsWith("p99"))
|
||||
.map(sample -> (GaugeMetricSample<?>) sample)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
Assertions.assertNotNull(p95Sample);
|
||||
Assertions.assertNotNull(p99Sample);
|
||||
|
||||
double p95 = p95Sample.applyAsDouble();
|
||||
double p99 = p99Sample.applyAsDouble();
|
||||
|
||||
//An error of less than 5% is allowed
|
||||
Assertions.assertTrue(Math.abs(1 - p95 / manualP95) < 0.05);
|
||||
Assertions.assertTrue(Math.abs(1 - p99 / manualP99) < 0.05);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ package org.apache.dubbo.metrics.collector;
|
|||
import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
|
||||
import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
|
||||
import org.apache.dubbo.config.ApplicationConfig;
|
||||
import org.apache.dubbo.metrics.model.ConfigCenterMetric;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
|
|
@ -32,14 +31,8 @@ import org.junit.jupiter.api.Test;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_APPLICATION_NAME;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_GROUP_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_INTERFACE_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_METHOD_KEY;
|
||||
import static org.apache.dubbo.common.constants.MetricsConstants.TAG_VERSION_KEY;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class ConfigCenterMetricsCollectorTest {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* 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.dubbo.metrics.collector.sample;
|
||||
|
||||
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
|
||||
import org.apache.dubbo.common.extension.ExtensionLoader;
|
||||
import org.apache.dubbo.common.store.DataStore;
|
||||
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
|
||||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
import org.apache.dubbo.metrics.model.ThreadPoolMetric;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_SERVICE_COMPONENT_KEY;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SuppressWarnings("all")
|
||||
public class ThreadPoolMetricsSamplerTest {
|
||||
|
||||
ThreadPoolMetricsSampler sampler;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
DefaultMetricsCollector collector = new DefaultMetricsCollector();
|
||||
sampler = new ThreadPoolMetricsSampler(collector);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSample() {
|
||||
|
||||
ExecutorService executorService = java.util.concurrent.Executors.newFixedThreadPool(5);
|
||||
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
|
||||
sampler.addExecutors("testPool", executorService);
|
||||
|
||||
List<MetricSample> metricSamples = sampler.sample();
|
||||
|
||||
Assertions.assertEquals(6, metricSamples.size());
|
||||
|
||||
boolean coreSizeFound = false;
|
||||
boolean maxSizeFound = false;
|
||||
boolean activeSizeFound = false;
|
||||
boolean threadCountFound = false;
|
||||
boolean queueSizeFound = false;
|
||||
boolean largestSizeFound = false;
|
||||
|
||||
for (MetricSample sample : metricSamples) {
|
||||
ThreadPoolMetric threadPoolMetric = ((ThreadPoolMetric) ((GaugeMetricSample) sample).getValue());
|
||||
switch (sample.getName()) {
|
||||
case "dubbo.thread.pool.core.size":
|
||||
coreSizeFound = true;
|
||||
Assertions.assertEquals(5, threadPoolMetric.getCorePoolSize());
|
||||
break;
|
||||
case "dubbo.thread.pool.largest.size":
|
||||
largestSizeFound = true;
|
||||
Assertions.assertEquals(0, threadPoolMetric.getLargestPoolSize());
|
||||
break;
|
||||
case "dubbo.thread.pool.max.size":
|
||||
maxSizeFound = true;
|
||||
Assertions.assertEquals(5, threadPoolMetric.getMaximumPoolSize());
|
||||
break;
|
||||
case "dubbo.thread.pool.active.size":
|
||||
activeSizeFound = true;
|
||||
Assertions.assertEquals(0, threadPoolMetric.getActiveCount());
|
||||
break;
|
||||
case "dubbo.thread.pool.thread.count":
|
||||
threadCountFound = true;
|
||||
Assertions.assertEquals(0, threadPoolMetric.getPoolSize());
|
||||
break;
|
||||
case "dubbo.thread.pool.queue.size":
|
||||
queueSizeFound = true;
|
||||
Assertions.assertEquals(0, threadPoolMetric.getQueueSize());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Assertions.assertTrue(coreSizeFound);
|
||||
Assertions.assertTrue(maxSizeFound);
|
||||
Assertions.assertTrue(activeSizeFound);
|
||||
Assertions.assertTrue(threadCountFound);
|
||||
Assertions.assertTrue(queueSizeFound);
|
||||
Assertions.assertTrue(largestSizeFound);
|
||||
|
||||
executorService.shutdown();
|
||||
}
|
||||
|
||||
private DefaultMetricsCollector collector;
|
||||
|
||||
private ThreadPoolMetricsSampler sampler2;
|
||||
|
||||
@Mock
|
||||
private ApplicationModel applicationModel;
|
||||
|
||||
@Mock
|
||||
ScopeBeanFactory scopeBeanFactory;
|
||||
|
||||
@Mock
|
||||
private DataStore dataStore;
|
||||
|
||||
@Mock
|
||||
private FrameworkExecutorRepository frameworkExecutorRepository;
|
||||
|
||||
@Mock
|
||||
private ExtensionLoader<DataStore> extensionLoader;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp2() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
|
||||
collector = new DefaultMetricsCollector();
|
||||
sampler2 = new ThreadPoolMetricsSampler(collector);
|
||||
|
||||
when(scopeBeanFactory.getBean(FrameworkExecutorRepository.class)).thenReturn(new FrameworkExecutorRepository());
|
||||
|
||||
collector.collectApplication(applicationModel);
|
||||
when(applicationModel.getBeanFactory()).thenReturn(scopeBeanFactory);
|
||||
when(applicationModel.getExtensionLoader(DataStore.class)).thenReturn(extensionLoader);
|
||||
when(extensionLoader.getDefaultExtension()).thenReturn(dataStore);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegistryDefaultSampleThreadPoolExecutor() throws NoSuchFieldException, IllegalAccessException {
|
||||
|
||||
Map<String, Object> serverExecutors = new HashMap<>();
|
||||
Map<String, Object> clientExecutors = new HashMap<>();
|
||||
|
||||
ExecutorService serverExecutor = Executors.newFixedThreadPool(5);
|
||||
ExecutorService clientExecutor = Executors.newFixedThreadPool(5);
|
||||
|
||||
serverExecutors.put("server1", serverExecutor);
|
||||
clientExecutors.put("client1", clientExecutor);
|
||||
|
||||
when(dataStore.get(EXECUTOR_SERVICE_COMPONENT_KEY)).thenReturn(serverExecutors);
|
||||
when(dataStore.get(CONSUMER_SHARED_EXECUTOR_SERVICE_COMPONENT_KEY)).thenReturn(clientExecutors);
|
||||
|
||||
when(frameworkExecutorRepository.getSharedExecutor()).thenReturn(Executors.newFixedThreadPool(5));
|
||||
|
||||
sampler2.registryDefaultSampleThreadPoolExecutor();
|
||||
|
||||
Field f = ThreadPoolMetricsSampler.class.getDeclaredField("sampleThreadPoolExecutor");
|
||||
f.setAccessible(true);
|
||||
Map<String,ThreadPoolExecutor> executors = (Map<String, ThreadPoolExecutor>) f.get(sampler2);
|
||||
|
||||
Assertions.assertEquals(3, executors.size());
|
||||
Assertions.assertTrue(executors.containsKey("DubboServerHandler-server1"));
|
||||
Assertions.assertTrue(executors.containsKey("DubboClientHandler-client1"));
|
||||
Assertions.assertTrue(executors.containsKey("sharedExecutor"));
|
||||
|
||||
serverExecutor.shutdown();
|
||||
clientExecutor.shutdown();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* 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.dubbo.metrics.sampler;
|
||||
|
||||
import org.apache.dubbo.metrics.collector.DefaultMetricsCollector;
|
||||
import org.apache.dubbo.metrics.collector.sample.MethodMetricsSampler;
|
||||
import org.apache.dubbo.metrics.event.MetricsEvent;
|
||||
import org.apache.dubbo.metrics.model.key.MetricsKey;
|
||||
import org.apache.dubbo.metrics.model.sample.CounterMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
import org.apache.dubbo.metrics.model.sample.MetricSample;
|
||||
import org.apache.dubbo.metrics.observation.MockInvocation;
|
||||
import org.apache.dubbo.rpc.Invocation;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class MethodMetricsTest {
|
||||
|
||||
private DefaultMetricsCollector collector;
|
||||
private MethodMetricsSampler sampler;
|
||||
|
||||
private Invocation invocation;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
collector = new DefaultMetricsCollector();
|
||||
sampler = new MethodMetricsSampler(collector);
|
||||
invocation = spy(new MockInvocation());
|
||||
when(invocation.getTargetServiceUniqueName()).thenReturn("TestService-1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRequestsCount() {
|
||||
final long requestTimes = 1000L;
|
||||
|
||||
//METRIC_REQUESTS
|
||||
for (long i = 0; i < requestTimes; i++) {
|
||||
sampler.inc(invocation, MetricsEvent.Type.TOTAL.getNameByType("provider"));
|
||||
}
|
||||
|
||||
List<MetricSample> samples = sampler.sample();
|
||||
|
||||
MetricSample requestsSample = samples.stream()
|
||||
.filter(sample -> MetricsKey.METRIC_REQUESTS.getNameByType("provider").equals(sample.getName()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
Assertions.assertNotNull(requestsSample, "METRIC_REQUESTS sample should not be null");
|
||||
Assertions.assertEquals(MetricSample.Type.COUNTER, requestsSample.getType(), "METRIC_REQUESTS sample should have a COUNTER type");
|
||||
Assertions.assertTrue(requestsSample instanceof CounterMetricSample);
|
||||
Assertions.assertEquals(requestTimes, ((CounterMetricSample) requestsSample).getValue().longValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRequestsProcessing() {
|
||||
final long requestTimes = 1000L;
|
||||
|
||||
//METRIC_REQUESTS
|
||||
for (long i = 0; i < requestTimes; i++) {
|
||||
sampler.inc(invocation, MetricsEvent.Type.PROCESSING.getNameByType("provider"));
|
||||
}
|
||||
|
||||
List<MetricSample> samples = sampler.sample();
|
||||
|
||||
MetricSample requestsSample = samples.stream()
|
||||
.filter(sample -> MetricsKey.METRIC_REQUESTS_PROCESSING.getNameByType("provider").equals(sample.getName()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
Assertions.assertNotNull(requestsSample, "METRIC_REQUESTS_PROCESSING sample should not be null");
|
||||
Assertions.assertEquals(MetricSample.Type.GAUGE, requestsSample.getType(), "METRIC_REQUESTS_PROCESSING sample should have a GAUGE type");
|
||||
Assertions.assertTrue(requestsSample instanceof GaugeMetricSample);
|
||||
Assertions.assertEquals(requestTimes, ((AtomicLong) ((GaugeMetricSample) requestsSample).getValue()).get());
|
||||
|
||||
for (long i = 0; i < requestTimes; i++) {
|
||||
sampler.dec(invocation, MetricsEvent.Type.PROCESSING.getNameByType("provider"));
|
||||
}
|
||||
|
||||
samples = sampler.sample();
|
||||
|
||||
requestsSample = samples.stream()
|
||||
.filter(sample -> MetricsKey.METRIC_REQUESTS_PROCESSING.getNameByType("provider").equals(sample.getName()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
Assertions.assertEquals(0, ((AtomicLong) ((GaugeMetricSample) requestsSample).getValue()).get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRequestSucceed() {
|
||||
final long requestTimes = 1000L;
|
||||
|
||||
//METRIC_REQUESTS_SUCCEED
|
||||
for (long i = 0; i < requestTimes; i++) {
|
||||
sampler.inc(invocation, MetricsEvent.Type.SUCCEED.getNameByType("provider"));
|
||||
}
|
||||
|
||||
List<MetricSample> samples = sampler.sample();
|
||||
|
||||
MetricSample requestsSample = samples.stream()
|
||||
.filter(sample -> MetricsKey.METRIC_REQUESTS_SUCCEED.getNameByType("provider").equals(sample.getName()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
Assertions.assertNotNull(requestsSample, "METRIC_REQUESTS_SUCCEED sample should not be null");
|
||||
Assertions.assertEquals(MetricSample.Type.COUNTER, requestsSample.getType(), "METRIC_REQUESTS_SUCCEED sample should have a COUNTER type");
|
||||
Assertions.assertTrue(requestsSample instanceof CounterMetricSample);
|
||||
Assertions.assertEquals(requestTimes, ((AtomicLong) ((CounterMetricSample) requestsSample).getValue()).get());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -21,15 +21,22 @@ import org.apache.dubbo.metrics.data.ApplicationStatComposite;
|
|||
import org.apache.dubbo.metrics.data.BaseStatComposite;
|
||||
import org.apache.dubbo.metrics.data.RtStatComposite;
|
||||
import org.apache.dubbo.metrics.data.ServiceStatComposite;
|
||||
import org.apache.dubbo.metrics.model.MetricsCategory;
|
||||
import org.apache.dubbo.metrics.model.container.LongContainer;
|
||||
import org.apache.dubbo.metrics.registry.RegistryMetricsConstants;
|
||||
import org.apache.dubbo.metrics.model.sample.GaugeMetricSample;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static org.apache.dubbo.metrics.model.key.MetricsKey.METRIC_RT_AVG;
|
||||
import static org.apache.dubbo.metrics.model.key.MetricsKey.METRIC_RT_MAX;
|
||||
import static org.apache.dubbo.metrics.model.key.MetricsKey.METRIC_RT_MIN;
|
||||
import static org.apache.dubbo.metrics.model.key.MetricsKey.REGISTER_METRIC_REQUESTS;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_NOTIFY;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_REGISTER;
|
||||
|
|
@ -37,6 +44,7 @@ import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE
|
|||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_SUBSCRIBE;
|
||||
import static org.apache.dubbo.metrics.registry.RegistryMetricsConstants.OP_TYPE_SUBSCRIBE_SERVICE;
|
||||
|
||||
|
||||
public class RegistryStatCompositeTest {
|
||||
|
||||
private final String applicationName = "app1";
|
||||
|
|
@ -77,4 +85,42 @@ public class RegistryStatCompositeTest {
|
|||
Optional<LongContainer<? extends Number>> subContainer = statComposite.getRtStatComposite().getRtStats().stream().filter(longContainer -> longContainer.specifyType(OP_TYPE_NOTIFY.getType())).findFirst();
|
||||
subContainer.ifPresent(v -> Assertions.assertEquals(10L, v.get(applicationName).longValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
void testCalcServiceKeyRt() {
|
||||
String applicationName = "TestApp";
|
||||
String serviceKey = "TestService";
|
||||
String registryOpType = OP_TYPE_REGISTER_SERVICE.getType();
|
||||
Long responseTime1 = 100L;
|
||||
Long responseTime2 = 200L;
|
||||
|
||||
statComposite.calcServiceKeyRt(applicationName, serviceKey, registryOpType, responseTime1);
|
||||
statComposite.calcServiceKeyRt(applicationName, serviceKey, registryOpType, responseTime2);
|
||||
|
||||
List<GaugeMetricSample> exportedRtMetrics = statComposite.export(MetricsCategory.RT);
|
||||
|
||||
GaugeMetricSample minSample = exportedRtMetrics.stream()
|
||||
.filter(sample -> sample.getTags().containsValue(applicationName))
|
||||
.filter(sample -> sample.getName().equals(METRIC_RT_MIN.getNameByType("register.service")))
|
||||
.findFirst().orElse(null);
|
||||
GaugeMetricSample maxSample = exportedRtMetrics.stream()
|
||||
.filter(sample -> sample.getTags().containsValue(applicationName))
|
||||
.filter(sample -> sample.getName().equals(METRIC_RT_MAX.getNameByType("register.service")))
|
||||
.findFirst().orElse(null);
|
||||
GaugeMetricSample avgSample = exportedRtMetrics.stream()
|
||||
.filter(sample -> sample.getTags().containsValue(applicationName))
|
||||
.filter(sample -> sample.getName().equals(METRIC_RT_AVG.getNameByType("register.service")))
|
||||
.findFirst().orElse(null);
|
||||
|
||||
Assertions.assertNotNull(minSample);
|
||||
Assertions.assertNotNull(maxSample);
|
||||
Assertions.assertNotNull(avgSample);
|
||||
|
||||
Assertions.assertEquals(responseTime1, minSample.applyAsLong());
|
||||
Assertions.assertEquals(responseTime2, maxSample.applyAsLong());
|
||||
Assertions.assertEquals((responseTime1 + responseTime2) / 2, avgSample.applyAsLong());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue