[ISSUE#13183] Add client metrics switch. (#13191)
Continuous Integration / ci (8, ubuntu-latest) (push) Has been cancelled Details
Integration Test / test (11, ubuntu-latest) (push) Has been cancelled Details
Integration Test / test (11.0.3, ubuntu-latest) (push) Has been cancelled Details
Integration Test / test (8, ubuntu-latest) (push) Has been cancelled Details
Integration Test / test (8.0.192, ubuntu-latest) (push) Has been cancelled Details
PUSH-CI / Build dist tar (push) Has been cancelled Details
PUSH-CI / Docker images (centos, 8) (push) Has been cancelled Details
PUSH-CI / Deploy nacos (push) Has been cancelled Details
PUSH-CI / Java e2e Test (push) Has been cancelled Details
PUSH-CI / GO E2E Test (push) Has been cancelled Details
PUSH-CI / Cpp E2E Test (push) Has been cancelled Details
PUSH-CI / Csharp E2E Test (push) Has been cancelled Details
PUSH-CI / Nodejs E2E Test (push) Has been cancelled Details
PUSH-CI / Python E2E Test (push) Has been cancelled Details
PUSH-CI / Clean (push) Has been cancelled Details

This commit is contained in:
Matthew 2025-03-26 11:25:36 +08:00 committed by GitHub
parent 83e145bcb5
commit 551c203c8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 376 additions and 16 deletions

View File

@ -130,4 +130,9 @@ public class PropertyKeyConst {
public static final String ALIBABA_ALIWARE_ENDPOINT_URL = "ALIBABA_ALIWARE_ENDPOINT_URL";
}
}
/**
* Client Metric Switch.
*/
public static final String ENABLE_CLIENT_METRICS = "enableClientMetrics";
}

View File

@ -151,6 +151,8 @@ public class ClientWorker implements Closeable {
private static final int THREAD_MULTIPLE = 1;
private boolean enableClientMetrics = true;
/**
* index(taskId)-> total cache count for this taskId.
*/
@ -298,7 +300,13 @@ public class ClientWorker implements Closeable {
}
LOGGER.info("[{}] [unsubscribe] {}", agent.getName(), groupKey);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
if (enableClientMetrics) {
try {
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
} catch (Throwable t) {
LOGGER.error("Failed to update metrics for listen config count", t);
}
}
}
/**
@ -373,7 +381,13 @@ public class ClientWorker implements Closeable {
LOGGER.info("[{}] [subscribe] {}", this.agent.getName(), key);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
if (enableClientMetrics) {
try {
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
} catch (Throwable t) {
LOGGER.error("Failed to update metrics for listen config count", t);
}
}
return cache;
}
@ -420,7 +434,13 @@ public class ClientWorker implements Closeable {
}
LOGGER.info("[{}] [subscribe] {}", agent.getName(), key);
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
if (enableClientMetrics) {
try {
MetricsMonitor.getListenConfigCountMonitor().set(cacheMap.get().size());
} catch (Throwable t) {
LOGGER.error("Failed to update metrics for listen config count", t);
}
}
return cache;
}
@ -523,6 +543,8 @@ public class ClientWorker implements Closeable {
this.enableRemoteSyncConfig = Boolean.parseBoolean(
properties.getProperty(PropertyKeyConst.ENABLE_REMOTE_SYNC_CONFIG));
this.enableClientMetrics = Boolean.parseBoolean(
properties.getProperty(PropertyKeyConst.ENABLE_CLIENT_METRICS, "true"));
initAppLabels(properties.getProperties(SourceType.PROPERTIES));
}

View File

@ -57,6 +57,8 @@ public class ServiceInfoHolder implements Closeable {
private String notifierEventScope;
private boolean enableClientMetrics = true;
public ServiceInfoHolder(String namespace, String notifierEventScope, NacosClientProperties properties) {
cacheDir = CacheDirUtil.initCacheDir(namespace, properties);
instancesDiffer = new InstancesDiffer();
@ -68,6 +70,8 @@ public class ServiceInfoHolder implements Closeable {
this.failoverReactor = new FailoverReactor(this, notifierEventScope);
this.pushEmptyProtection = isPushEmptyProtect(properties);
this.notifierEventScope = notifierEventScope;
this.enableClientMetrics = Boolean.parseBoolean(
properties.getProperty(PropertyKeyConst.ENABLE_CLIENT_METRICS, "true"));
}
private boolean isLoadCacheAtStart(NacosClientProperties properties) {
@ -136,7 +140,15 @@ public class ServiceInfoHolder implements Closeable {
if (StringUtils.isBlank(serviceInfo.getJsonFromServer())) {
serviceInfo.setJsonFromServer(JacksonUtils.toJson(serviceInfo));
}
MetricsMonitor.getServiceInfoMapSizeMonitor().set(serviceInfoMap.size());
if (enableClientMetrics) {
try {
MetricsMonitor.getServiceInfoMapSizeMonitor().set(serviceInfoMap.size());
} catch (Throwable t) {
NAMING_LOGGER.error("Failed to update metrics for service info map size", t);
}
}
if (diff.hasDifferent()) {
NAMING_LOGGER.info("current ips:({}) service: {} -> {}", serviceInfo.ipCount(), serviceKey,
JacksonUtils.toJson(serviceInfo.getHosts()));

View File

@ -16,6 +16,7 @@
package com.alibaba.nacos.client.naming.remote.gprc;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.ability.constant.AbilityKey;
import com.alibaba.nacos.api.ability.constant.AbilityStatus;
import com.alibaba.nacos.api.common.Constants;
@ -94,6 +95,8 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
private final NamingGrpcRedoService redoService;
private boolean enableClientMetrics = true;
public NamingGrpcClientProxy(String namespaceId, SecurityProxy securityProxy, ServerListFactory serverListFactory,
NacosClientProperties properties, ServiceInfoHolder serviceInfoHolder) throws NacosException {
super(securityProxy);
@ -108,6 +111,8 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
.createGrpcClientConfig(properties.asProperties(), labels);
this.rpcClient = RpcClientFactory.createClient(uuid, ConnectionType.GRPC, grpcClientConfig);
this.redoService = new NamingGrpcRedoService(this, properties);
this.enableClientMetrics = Boolean.parseBoolean(
properties.getProperty(PropertyKeyConst.ENABLE_CLIENT_METRICS, "true"));
NAMING_LOGGER.info("Create naming rpc client for uuid->{}", uuid);
start(serverListFactory, serviceInfoHolder);
}
@ -478,13 +483,21 @@ public class NamingGrpcClientProxy extends AbstractNamingClientProxy {
* @param response The response object containing registration result information, or null if registration failed.
*/
private void recordRequestFailedMetrics(AbstractNamingRequest request, Exception exception, Response response) {
if (Objects.isNull(response)) {
MetricsMonitor.getNamingRequestFailedMonitor(request.getClass().getSimpleName(), MONITOR_LABEL_NONE,
MONITOR_LABEL_NONE, exception.getClass().getSimpleName()).inc();
} else {
MetricsMonitor.getNamingRequestFailedMonitor(request.getClass().getSimpleName(),
String.valueOf(response.getResultCode()), String.valueOf(response.getErrorCode()),
MONITOR_LABEL_NONE).inc();
if (!enableClientMetrics) {
return;
}
try {
if (Objects.isNull(response)) {
MetricsMonitor.getNamingRequestFailedMonitor(request.getClass().getSimpleName(), MONITOR_LABEL_NONE,
MONITOR_LABEL_NONE, exception.getClass().getSimpleName()).inc();
} else {
MetricsMonitor.getNamingRequestFailedMonitor(request.getClass().getSimpleName(),
String.valueOf(response.getResultCode()), String.valueOf(response.getErrorCode()),
MONITOR_LABEL_NONE).inc();
}
} catch (Throwable t) {
NAMING_LOGGER.warn("Fail to record metrics for request {}", request.getClass().getSimpleName(), t);
}
}

View File

@ -108,6 +108,8 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
private int serverPort = DEFAULT_SERVER_PORT;
private boolean enableClientMetrics = true;
public NamingHttpClientProxy(String namespaceId, SecurityProxy securityProxy, NamingServerListManager serverListManager,
NacosClientProperties properties) {
super(securityProxy);
@ -116,6 +118,8 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
this.namespaceId = namespaceId;
this.maxRetry = ConvertUtils.toInt(properties.getProperty(PropertyKeyConst.NAMING_REQUEST_DOMAIN_RETRY_COUNT,
String.valueOf(UtilAndComs.REQUEST_DOMAIN_RETRY_COUNT)));
this.enableClientMetrics = Boolean.parseBoolean(
properties.getProperty(PropertyKeyConst.ENABLE_CLIENT_METRICS, "true"));
}
@Override
@ -431,8 +435,15 @@ public class NamingHttpClientProxy extends AbstractNamingClientProxy {
Query.newInstance().initParams(params), body, method, String.class);
end = System.currentTimeMillis();
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(restResult.getCode()))
.observe(end - start);
if (enableClientMetrics) {
try {
MetricsMonitor.getNamingRequestMonitor(method, url, String.valueOf(restResult.getCode()))
.observe(end - start);
} catch (Throwable t) {
NAMING_LOGGER.error("Failed to record metrics. Method: {}, URL: {}, HTTP Status Code: {}",
method, url, restResult.getCode(), t);
}
}
if (restResult.ok()) {
return restResult.getData();

View File

@ -36,6 +36,7 @@ import com.alibaba.nacos.client.config.common.GroupKey;
import com.alibaba.nacos.client.config.filter.impl.ConfigFilterChainManager;
import com.alibaba.nacos.client.config.filter.impl.ConfigResponse;
import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.common.remote.ConnectionType;
import com.alibaba.nacos.common.remote.client.RpcClient;
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
@ -43,6 +44,7 @@ import com.alibaba.nacos.common.remote.client.grpc.GrpcClientConfig;
import com.alibaba.nacos.common.utils.JacksonUtils;
import com.alibaba.nacos.common.utils.MD5Utils;
import com.fasterxml.jackson.databind.JsonNode;
import io.prometheus.client.Gauge;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -51,10 +53,12 @@ import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.slf4j.Logger;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -77,7 +81,11 @@ import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@ExtendWith(MockitoExtension.class)
class ClientWorkerTest {
@ -95,8 +103,11 @@ class ClientWorkerTest {
private ClientWorker clientWorkerSpy;
@Mock
private Logger logger;
@BeforeEach
void before() {
void before() throws Exception {
rpcClientFactoryMockedStatic = Mockito.mockStatic(RpcClientFactory.class);
rpcClientFactoryMockedStatic.when(
@ -107,7 +118,7 @@ class ClientWorkerTest {
Properties properties = new Properties();
properties.put(PropertyKeyConst.NAMESPACE, TEST_NAMESPACE);
ConfigFilterChainManager filter = new ConfigFilterChainManager(properties);
ConfigServerListManager serverListManager = Mockito.mock(ConfigServerListManager.class);
ConfigServerListManager serverListManager = mock(ConfigServerListManager.class);
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
try {
clientWorker = new ClientWorker(filter, serverListManager, nacosClientProperties);
@ -115,6 +126,14 @@ class ClientWorkerTest {
throw new RuntimeException(e);
}
clientWorkerSpy = Mockito.spy(clientWorker);
Field loggerField = ClientWorker.class.getDeclaredField("LOGGER");
loggerField.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(loggerField, loggerField.getModifiers() & ~Modifier.FINAL);
loggerField.set(null, logger);
}
@AfterEach
@ -775,4 +794,176 @@ class ClientWorkerTest {
boolean result = clientWorker.removeConfig("a", "b", "c", "tag");
assertFalse(result);
}
@Test
void testRemoveCacheWithMetricsEnabled() throws Exception {
String dataId = "testDataId";
String group = "testGroup";
String tenant = "testTenant";
Properties prop = new Properties();
prop.put("enableClientMetrics", "true");
ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties());
ConfigServerListManager agent = mock(ConfigServerListManager.class);
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
final ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getListenConfigCountMonitor).thenReturn(mockGaugeChild);
clientWorker.removeCache(dataId, group, tenant);
verify(mockGaugeChild, times(1)).set(0);
}
}
@Test
void testRemoveCacheWithMetricsDisabled() throws Exception {
String dataId = "testDataId";
String group = "testGroup";
String tenant = "testTenant";
Properties prop = new Properties();
prop.put(PropertyKeyConst.ENABLE_CLIENT_METRICS, "false");
ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties());
ConfigServerListManager agent = mock(ConfigServerListManager.class);
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
final ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties);
clientWorkerSpy = Mockito.spy(clientWorker);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getListenConfigCountMonitor).thenReturn(mockGaugeChild);
clientWorker.removeCache(dataId, group, tenant);
verify(mockGaugeChild, times(0)).set(0);
}
}
@Test
void testRemoveCacheWithDefaultClientMetricsEnabled() throws Exception {
String dataId = "testDataId";
String group = "testGroup";
String tenant = "testTenant";
Properties prop = new Properties();
ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties());
ConfigServerListManager agent = mock(ConfigServerListManager.class);
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
final ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getListenConfigCountMonitor).thenReturn(mockGaugeChild);
clientWorker.removeCache(dataId, group, tenant);
verify(mockGaugeChild, times(1)).set(0);
}
}
@Test
void testMetricsMonitorSetThrowsException() throws NacosException {
String dataId = "testDataId";
String group = "testGroup";
String tenant = "testTenant";
Properties prop = new Properties();
prop.put(PropertyKeyConst.ENABLE_CLIENT_METRICS, "true");
ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties());
ConfigServerListManager agent = mock(ConfigServerListManager.class);
final NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
final ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties);
clientWorkerSpy = Mockito.spy(clientWorker);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getListenConfigCountMonitor).thenReturn(mockGaugeChild);
RuntimeException exception = new RuntimeException("Mocked exception");
doThrow(exception).when(mockGaugeChild).set(0);
clientWorker.removeCache(dataId, group, tenant);
String groupKey = GroupKey.getKeyTenant(dataId, group, tenant);
verify(logger, times(1)).info("[{}] [unsubscribe] {}", null, groupKey);
verify(logger, times(1)).error("Failed to update metrics for listen config count", exception);
}
}
@Test
public void testAddCacheDataIfAbsentEnableClientMetricsTrue() throws NacosException {
String dataId = "testDataId";
String group = "testGroup";
String tenant = "testTenant";
Properties prop = new Properties();
prop.put(PropertyKeyConst.ENABLE_CLIENT_METRICS, "true");
ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties());
ConfigServerListManager agent = mock(ConfigServerListManager.class);
NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getListenConfigCountMonitor).thenReturn(mockGaugeChild);
clientWorker.addCacheDataIfAbsent(dataId, group, tenant);
verify(mockGaugeChild, times(1)).set(1);
}
}
@Test
public void testAddCacheDataIfAbsentEnableClientMetricsFalse() throws NacosException {
String dataId = "testDataId";
String group = "testGroup";
String tenant = "testTenant";
Properties prop = new Properties();
prop.put(PropertyKeyConst.ENABLE_CLIENT_METRICS, "false");
ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties());
ConfigServerListManager agent = mock(ConfigServerListManager.class);
NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
clientWorker.addCacheDataIfAbsent(dataId, group, tenant);
mockedMetricsMonitor.verify(MetricsMonitor::getListenConfigCountMonitor, never());
}
}
@Test
public void testAddCacheDataIfAbsentEnableClientMetricsNotSet() throws NacosException {
String dataId = "testDataId";
String group = "testGroup";
String tenant = "testTenant";
Properties prop = new Properties();
ConfigFilterChainManager filter = new ConfigFilterChainManager(new Properties());
ConfigServerListManager agent = mock(ConfigServerListManager.class);
NacosClientProperties nacosClientProperties = NacosClientProperties.PROTOTYPE.derive(prop);
ClientWorker clientWorker = new ClientWorker(filter, agent, nacosClientProperties);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getListenConfigCountMonitor).thenReturn(mockGaugeChild);
clientWorker.addCacheDataIfAbsent(dataId, group, tenant);
verify(mockGaugeChild, times(1)).set(1);
}
}
}

View File

@ -23,21 +23,31 @@ import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.client.env.NacosClientProperties;
import com.alibaba.nacos.client.monitor.MetricsMonitor;
import com.alibaba.nacos.client.naming.backups.FailoverReactor;
import io.prometheus.client.Gauge;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ScheduledExecutorService;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class ServiceInfoHolderTest {
@ -91,6 +101,102 @@ class ServiceInfoHolderTest {
assertEquals(info2, actual2);
}
@Test
void testProcessServiceInfoEnableClientMetricsTrue() {
ServiceInfoHolder holder = createServiceInfoHolder(true);
ServiceInfo info = new ServiceInfo("a@@b@@c");
Instance instance1 = createInstance("1.1.1.1", 1);
Instance instance2 = createInstance("1.1.1.2", 2);
List<Instance> hosts = new ArrayList<>();
hosts.add(instance1);
hosts.add(instance2);
info.setHosts(hosts);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getServiceInfoMapSizeMonitor).thenReturn(mockGaugeChild);
holder.processServiceInfo(info);
verify(mockGaugeChild, times(1)).set(1);
}
}
@Test
void testProcessServiceInfoEnableClientMetricsFalse() {
ServiceInfoHolder holder = createServiceInfoHolder(false);
ServiceInfo info = new ServiceInfo("a@@b@@c");
Instance instance1 = createInstance("1.1.1.1", 1);
Instance instance2 = createInstance("1.1.1.2", 2);
List<Instance> hosts = new ArrayList<>();
hosts.add(instance1);
hosts.add(instance2);
info.setHosts(hosts);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
holder.processServiceInfo(info);
mockedMetricsMonitor.verify(MetricsMonitor::getServiceInfoMapSizeMonitor, never());
}
}
@Test
void testProcessServiceInfoEnableClientMetricsNotSet() {
ServiceInfoHolder holder = createServiceInfoHolder(null);
ServiceInfo info = new ServiceInfo("a@@b@@c");
Instance instance1 = createInstance("1.1.1.1", 1);
Instance instance2 = createInstance("1.1.1.2", 2);
List<Instance> hosts = new ArrayList<>();
hosts.add(instance1);
hosts.add(instance2);
info.setHosts(hosts);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getServiceInfoMapSizeMonitor).thenReturn(mockGaugeChild);
holder.processServiceInfo(info);
verify(mockGaugeChild, times(1)).set(1);
}
}
@Test
void testProcessServiceInfoSetThrowsException() {
ServiceInfoHolder holder = createServiceInfoHolder(true);
ServiceInfo info = new ServiceInfo("a@@b@@c");
Instance instance1 = createInstance("1.1.1.1", 1);
Instance instance2 = createInstance("1.1.1.2", 2);
List<Instance> hosts = new ArrayList<>();
hosts.add(instance1);
hosts.add(instance2);
info.setHosts(hosts);
Gauge.Child mockGaugeChild = mock(Gauge.Child.class);
RuntimeException exception = new RuntimeException("Mocked exception");
try (MockedStatic<MetricsMonitor> mockedMetricsMonitor = Mockito.mockStatic(MetricsMonitor.class)) {
mockedMetricsMonitor.when(MetricsMonitor::getServiceInfoMapSizeMonitor).thenReturn(mockGaugeChild);
doThrow(exception).when(mockGaugeChild).set(anyInt());
ServiceInfo actual2 = holder.processServiceInfo(info);
assertEquals(info, actual2);
}
}
private ServiceInfoHolder createServiceInfoHolder(Boolean enableClientMetrics) {
Properties properties = new Properties();
if (enableClientMetrics != null) {
properties.put(PropertyKeyConst.ENABLE_CLIENT_METRICS, String.valueOf(enableClientMetrics));
}
NacosClientProperties clientProperties = NacosClientProperties.PROTOTYPE.derive(properties);
String namespace = "test-namespace";
String notifierEventScope = "scope-001";
return new ServiceInfoHolder(namespace, notifierEventScope, clientProperties);
}
private Instance createInstance(String ip, int port) {
Instance instance = new Instance();
instance.setIp(ip);