diff --git a/eureka-client/src/main/java/com/netflix/discovery/DiscoveryClient.java b/eureka-client/src/main/java/com/netflix/discovery/DiscoveryClient.java index 569a1623a..dc0c54862 100644 --- a/eureka-client/src/main/java/com/netflix/discovery/DiscoveryClient.java +++ b/eureka-client/src/main/java/com/netflix/discovery/DiscoveryClient.java @@ -129,6 +129,16 @@ public class DiscoveryClient implements EurekaClient { private final Timer FETCH_REGISTRY_TIMER = SpectatorUtil.timer(PREFIX + "FetchRegistry", DiscoveryClient.class); private final Counter REREGISTER_COUNTER = SpectatorUtil.counter(PREFIX + "Reregister", DiscoveryClient.class); + // Lookup counters + private final Counter LOOKUP_GET_APPLICATION = SpectatorUtil.counter(PREFIX + "Lookup", "getApplication", DiscoveryClient.class); + private final Counter LOOKUP_GET_APPLICATIONS = SpectatorUtil.counter(PREFIX + "Lookup", "getApplications", DiscoveryClient.class); + private final Counter LOOKUP_GET_APPLICATIONS_FOR_A_REGION = SpectatorUtil.counter(PREFIX + "Lookup", "getApplicationsForARegion", DiscoveryClient.class); + private final Counter LOOKUP_GET_INSTANCES_BY_ID = SpectatorUtil.counter(PREFIX + "Lookup", "getInstancesById", DiscoveryClient.class); + private final Counter LOOKUP_GET_INSTANCES_BY_VIP = SpectatorUtil.counter(PREFIX + "Lookup", "getInstancesByVipAddress", DiscoveryClient.class); + private final Counter LOOKUP_GET_INSTANCES_BY_VIP_AND_APP = SpectatorUtil.counter(PREFIX + "Lookup", "getInstancesByVipAddressAndAppName", DiscoveryClient.class); + private final Counter LOOKUP_GET_NEXT_SERVER = SpectatorUtil.counter(PREFIX + "Lookup", "getNextServerFromEureka", DiscoveryClient.class); + private final Counter LOOKUP_GET_APPLICATIONS_SERVICE_URL = SpectatorUtil.counter(PREFIX + "Lookup", "getApplicationsServiceUrl", DiscoveryClient.class); + // instance variables /** * A scheduler to be used for the following 3 tasks: @@ -459,7 +469,7 @@ public Thread newThread(Runnable r) { private void scheduleServerEndpointTask(EurekaTransport eurekaTransport, AbstractDiscoveryClientOptionalArgs args) { - + Collection additionalFilters = args == null ? Collections.emptyList() : args.additionalFilters; @@ -560,6 +570,7 @@ public ApplicationInfoManager getApplicationInfoManager() { */ @Override public Application getApplication(String appName) { + LOOKUP_GET_APPLICATION.increment(); return getApplications().getRegisteredApplications(appName); } @@ -570,11 +581,13 @@ public Application getApplication(String appName) { */ @Override public Applications getApplications() { + LOOKUP_GET_APPLICATIONS.increment(); return localRegionApps.get(); } @Override public Applications getApplicationsForARegion(@Nullable String region) { + LOOKUP_GET_APPLICATIONS_FOR_A_REGION.increment(); if (instanceRegionChecker.isLocalRegion(region)) { return localRegionApps.get(); } else { @@ -600,6 +613,7 @@ public Set getAllKnownRegions() { */ @Override public List getInstancesById(String id) { + LOOKUP_GET_INSTANCES_BY_ID.increment(); List instancesList = new ArrayList<>(); for (Application app : this.getApplications() .getRegisteredApplications()) { @@ -684,6 +698,7 @@ public List getInstancesByVipAddress(String vipAddress, boolean se @Override public List getInstancesByVipAddress(String vipAddress, boolean secure, @Nullable String region) { + LOOKUP_GET_INSTANCES_BY_VIP.increment(); if (vipAddress == null) { throw new IllegalArgumentException( "Supplied VIP Address cannot be null"); @@ -704,9 +719,7 @@ public List getInstancesByVipAddress(String vipAddress, boolean se return applications.getInstancesByVirtualHostName(vipAddress); } else { return applications.getInstancesBySecureVirtualHostName(vipAddress); - } - } /** @@ -725,6 +738,7 @@ public List getInstancesByVipAddress(String vipAddress, boolean se @Override public List getInstancesByVipAddressAndAppName( String vipAddress, String appName, boolean secure) { + LOOKUP_GET_INSTANCES_BY_VIP_AND_APP.increment(); List result = new ArrayList<>(); if (vipAddress == null && appName == null) { @@ -779,6 +793,7 @@ public List getInstancesByVipAddressAndAppName( */ @Override public InstanceInfo getNextServerFromEureka(String virtualHostname, boolean secure) { + LOOKUP_GET_NEXT_SERVER.increment(); List instanceInfoList = this.getInstancesByVipAddress( virtualHostname, secure); if (instanceInfoList == null || instanceInfoList.isEmpty()) { @@ -800,6 +815,7 @@ public InstanceInfo getNextServerFromEureka(String virtualHostname, boolean secu */ @Override public Applications getApplications(String serviceUrl) { + LOOKUP_GET_APPLICATIONS_SERVICE_URL.increment(); try { EurekaHttpResponse response = clientConfig.getRegistryRefreshSingleVipAddress() == null ? eurekaTransport.queryClient.getApplications() diff --git a/eureka-client/src/test/java/com/netflix/discovery/DiscoveryClientRegistryTest.java b/eureka-client/src/test/java/com/netflix/discovery/DiscoveryClientRegistryTest.java index a63566758..62afb14b8 100644 --- a/eureka-client/src/test/java/com/netflix/discovery/DiscoveryClientRegistryTest.java +++ b/eureka-client/src/test/java/com/netflix/discovery/DiscoveryClientRegistryTest.java @@ -16,6 +16,10 @@ import com.netflix.discovery.shared.transport.EurekaHttpResponse; import com.netflix.discovery.shared.transport.SimpleEurekaHttpServer; import com.netflix.discovery.util.InstanceInfoGenerator; +import com.netflix.spectator.api.Counter; +import com.netflix.spectator.api.DefaultRegistry; +import com.netflix.spectator.api.Registry; +import com.netflix.spectator.api.Spectator; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -52,6 +56,7 @@ public class DiscoveryClientRegistryTest { private static final EurekaHttpClient requestHandler = mock(EurekaHttpClient.class); private static SimpleEurekaHttpServer eurekaHttpServer; + private static DefaultRegistry testRegistry; @Rule public DiscoveryClientResource discoveryClientResource = DiscoveryClientResource.newBuilder() @@ -67,6 +72,8 @@ public class DiscoveryClientRegistryTest { @BeforeClass public static void setUpClass() throws IOException { eurekaHttpServer = new SimpleEurekaHttpServer(requestHandler); + testRegistry = new DefaultRegistry(); + Spectator.globalRegistry().add(testRegistry); } @AfterClass @@ -74,6 +81,9 @@ public static void tearDownClass() throws Exception { if (eurekaHttpServer != null) { eurekaHttpServer.shutdown(); } + if (testRegistry != null) { + Spectator.globalRegistry().remove(testRegistry); + } } @Before @@ -314,6 +324,28 @@ public void testEurekaClientPeriodicCacheRefreshForDeleteAndNoApplication() thro assertEquals(client.getApplications().getRegisteredApplications(), new ArrayList<>()); } + @Test + public void testLookupMetricsIncremented() throws Exception { + Applications applications = InstanceInfoGenerator.newBuilder(2, "app1").build().toApplications(); + InstanceInfo instance = applications.getRegisteredApplications("app1").getInstances().get(0); + String vipAddress = instance.getVIPAddress(); + + when(requestHandler.getApplications(TEST_REMOTE_REGION)).thenReturn( + anEurekaHttpResponse(200, applications).type(MediaType.APPLICATION_JSON_TYPE).build() + ); + + Registry registry = Spectator.globalRegistry(); + Counter vipCounter = registry.counter( + registry.createId("DiscoveryClient_Lookup") + .withTag("id", "getInstancesByVipAddress") + .withTag("class", "DiscoveryClient")); + long initialCount = vipCounter.count(); + + discoveryClientResource.getClient().getInstancesByVipAddress(vipAddress, false); + + assertThat(vipCounter.count(), is(equalTo(initialCount + 1))); + } + /** * There is a bug, because of which remote registry data structures are not initialized during full registry fetch, only during delta. */