diff --git a/build.gradle b/build.gradle
index a1d1c1f414..0215430ab2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -42,8 +42,7 @@ allprojects {
commonsConfigurationVersion = '1.10'
jsr305Version = '3.0.2'
guiceVersion = '4.1.0'
- spectatorVersion = '1.7.3'
- slf4jVersion = '1.7.36'
+ servoVersion = '0.12.21'
governatorVersion = '1.17.5'
archaiusVersion = '0.7.6'
jacksonVersion = '2.10.5'
diff --git a/eureka-client-archaius2/build.gradle b/eureka-client-archaius2/build.gradle
index 8917937257..82ea351f88 100644
--- a/eureka-client-archaius2/build.gradle
+++ b/eureka-client-archaius2/build.gradle
@@ -1,7 +1,6 @@
apply plugin: 'nebula.test-jar'
def archaius2Version = '2.1.7'
-def slf4jVersion = '1.7.36'
sourceSets {
test {
@@ -15,8 +14,6 @@ dependencies {
// archaius2
compile "com.netflix.archaius:archaius2-core:${archaius2Version}"
compile "com.netflix.archaius:archaius2-api:${archaius2Version}"
- compile "org.slf4j:slf4j-api:${slf4jVersion}"
- compile "com.netflix.spectator:spectator-api:${spectatorVersion}"
testCompile project(':eureka-test-utils')
diff --git a/eureka-client-jersey2/build.gradle b/eureka-client-jersey2/build.gradle
index 09072fbbef..2eab907353 100644
--- a/eureka-client-jersey2/build.gradle
+++ b/eureka-client-jersey2/build.gradle
@@ -27,8 +27,6 @@ dependencies {
compile project(':eureka-client')
compile 'org.glassfish.jersey.core:jersey-client:2.23.1'
compile 'org.glassfish.jersey.connectors:jersey-apache-connector:2.23.1'
- compile "org.slf4j:slf4j-api:1.7.36"
- compile 'com.netflix.spectator:spectator-api:1.7.3'
testCompile (project(':eureka-test-utils')) {
// exclude all transitives to avoid bringing in jersey1 eureka-core
diff --git a/eureka-client-jersey2/src/main/java/com/netflix/discovery/shared/transport/jersey2/EurekaJersey2ClientImpl.java b/eureka-client-jersey2/src/main/java/com/netflix/discovery/shared/transport/jersey2/EurekaJersey2ClientImpl.java
index 8cc6c0b25c..8e1b3ff51e 100644
--- a/eureka-client-jersey2/src/main/java/com/netflix/discovery/shared/transport/jersey2/EurekaJersey2ClientImpl.java
+++ b/eureka-client-jersey2/src/main/java/com/netflix/discovery/shared/transport/jersey2/EurekaJersey2ClientImpl.java
@@ -2,10 +2,6 @@
import static com.netflix.discovery.util.DiscoveryBuildInfo.buildVersion;
-import com.netflix.discovery.util.ServoUtil;
-import com.netflix.spectator.api.Counter;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.Timer;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
@@ -40,6 +36,12 @@
import com.netflix.discovery.converters.wrappers.DecoderWrapper;
import com.netflix.discovery.converters.wrappers.EncoderWrapper;
import com.netflix.discovery.provider.DiscoveryJerseyProvider;
+import com.netflix.servo.monitor.BasicCounter;
+import com.netflix.servo.monitor.BasicTimer;
+import com.netflix.servo.monitor.Counter;
+import com.netflix.servo.monitor.MonitorConfig;
+import com.netflix.servo.monitor.Monitors;
+import com.netflix.servo.monitor.Stopwatch;
/**
* @author Tomasz Bak
@@ -323,19 +325,24 @@ private PoolingHttpClientConnectionManager createCustomSslCM() {
private class ConnectionCleanerTask implements Runnable {
private final int connectionIdleTimeout;
- private final Timer executionTimeStats;
+ private final BasicTimer executionTimeStats;
private final Counter cleanupFailed;
private ConnectionCleanerTask(int connectionIdleTimeout) {
this.connectionIdleTimeout = connectionIdleTimeout;
- final com.netflix.spectator.api.Registry registry = Spectator.globalRegistry();
- executionTimeStats = registry.timer("Eureka-Connection-Cleaner-Time");
- cleanupFailed = registry.counter("Eureka-Connection-Cleaner-Failure");
+ MonitorConfig.Builder monitorConfigBuilder = MonitorConfig.builder("Eureka-Connection-Cleaner-Time");
+ executionTimeStats = new BasicTimer(monitorConfigBuilder.build());
+ cleanupFailed = new BasicCounter(MonitorConfig.builder("Eureka-Connection-Cleaner-Failure").build());
+ try {
+ Monitors.registerObject(this);
+ } catch (Exception e) {
+ s_logger.error("Unable to register with servo.", e);
+ }
}
@Override
public void run() {
- long monotonicTime = ServoUtil.time(executionTimeStats);
+ Stopwatch start = executionTimeStats.start();
try {
HttpClientConnectionManager cm = (HttpClientConnectionManager) apacheHttpClient
.getConfiguration()
@@ -345,8 +352,11 @@ public void run() {
s_logger.error("Cannot clean connections", e);
cleanupFailed.increment();
} finally {
- ServoUtil.record(executionTimeStats, monotonicTime);
+ if (null != start) {
+ start.stop();
+ }
}
+
}
}
}
\ No newline at end of file
diff --git a/eureka-client/build.gradle b/eureka-client/build.gradle
index a992aca42e..a27b477cb0 100644
--- a/eureka-client/build.gradle
+++ b/eureka-client/build.gradle
@@ -6,13 +6,11 @@ configurations.all {
}
dependencies {
+ compile "com.netflix.netflix-commons:netflix-eventbus:0.3.0"
compile 'com.thoughtworks.xstream:xstream:1.4.19'
compile "com.netflix.archaius:archaius-core:${archaiusVersion}"
compile 'javax.ws.rs:jsr311-api:1.1.1'
- implementation "com.netflix.spectator:spectator-api:${spectatorVersion}"
- implementation "org.slf4j:slf4j-api:${slf4jVersion}"
- implementation "com.netflix.netflix-commons:netflix-eventbus:0.3.0"
- implementation "javax.annotation:javax.annotation-api:1.2"
+ compile "com.netflix.servo:servo-core:${servoVersion}"
compile "com.sun.jersey:jersey-core:${jerseyVersion}"
compile "com.sun.jersey:jersey-client:${jerseyVersion}"
compile "com.sun.jersey.contribs:jersey-apache-client4:${jerseyVersion}"
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 aac46213c3..e04a778b1a 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/DiscoveryClient.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/DiscoveryClient.java
@@ -18,14 +18,7 @@
import static com.netflix.discovery.EurekaClientNames.METRIC_REGISTRATION_PREFIX;
import static com.netflix.discovery.EurekaClientNames.METRIC_REGISTRY_PREFIX;
-import static com.netflix.spectator.api.Spectator.globalRegistry;
-
-import com.netflix.discovery.util.ServoUtil;
-import com.netflix.spectator.api.Counter;
-import com.netflix.spectator.api.Registry;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.Timer;
-import com.netflix.spectator.api.patterns.PolledMeter;
+
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -90,6 +83,10 @@
import com.netflix.discovery.shared.transport.jersey.Jersey1TransportClientFactories;
import com.netflix.discovery.shared.transport.jersey.TransportClientFactories;
import com.netflix.discovery.util.ThresholdLevelsMetric;
+import com.netflix.servo.annotations.DataSourceType;
+import com.netflix.servo.monitor.Counter;
+import com.netflix.servo.monitor.Monitors;
+import com.netflix.servo.monitor.Stopwatch;
/**
* The class that is instrumental for interactions with Eureka Server.
@@ -133,10 +130,11 @@ public class DiscoveryClient implements EurekaClient {
// Timers
private static final String PREFIX = "DiscoveryClient_";
- private final Counter RECONCILE_HASH_CODES_MISMATCH = globalRegistry().counter(PREFIX + "ReconcileHashCodeMismatch");
- private final Timer FETCH_REGISTRY_TIMER = globalRegistry().timer(PREFIX + "FetchRegistry");
- private final Counter REREGISTER_COUNTER = globalRegistry().counter(PREFIX
- + "Reregister");
+ private final Counter RECONCILE_HASH_CODES_MISMATCH = Monitors.newCounter(PREFIX + "ReconcileHashCodeMismatch");
+ private final com.netflix.servo.monitor.Timer FETCH_REGISTRY_TIMER = Monitors
+ .newTimer(PREFIX + "FetchRegistry");
+ private final Counter REREGISTER_COUNTER = Monitors.newCounter(PREFIX
+ + "Reregister");
// instance variables
/**
@@ -180,10 +178,7 @@ public class DiscoveryClient implements EurekaClient {
private InstanceInfoReplicator instanceInfoReplicator;
- private final AtomicInteger registrySize = PolledMeter
- .using(Spectator.globalRegistry())
- .withName(METRIC_REGISTRY_PREFIX + "localRegistrySize")
- .monitorValue(new AtomicInteger());
+ private volatile int registrySize = 0;
private volatile long lastSuccessfulRegistryFetchTimestamp = -1;
private volatile long lastSuccessfulHeartbeatTimestamp = -1;
private final ThresholdLevelsMetric heartbeatStalenessMonitor;
@@ -367,19 +362,12 @@ public synchronized BackupRegistry get() {
} else {
this.registryStalenessMonitor = ThresholdLevelsMetric.NO_OP_METRIC;
}
- final Registry registry = globalRegistry();
- PolledMeter.using(registry)
- .withName(METRIC_REGISTRY_PREFIX + "lastSuccessfulRegistryFetchTimePeriod")
- .monitorValue(this, DiscoveryClient::getLastSuccessfulRegistryFetchTimePeriodInternal);
if (config.shouldRegisterWithEureka()) {
this.heartbeatStalenessMonitor = new ThresholdLevelsMetric(this, METRIC_REGISTRATION_PREFIX + "lastHeartbeatSec_", new long[]{15L, 30L, 60L, 120L, 240L, 480L});
} else {
this.heartbeatStalenessMonitor = ThresholdLevelsMetric.NO_OP_METRIC;
}
- PolledMeter.using(registry)
- .withName(METRIC_REGISTRATION_PREFIX + "lastSuccessfulHeartbeatTimePeriod")
- .monitorValue(this, DiscoveryClient::getLastSuccessfulHeartbeatTimePeriodInternal);
logger.info("Initializing Eureka in region {}", clientConfig.getRegion());
@@ -398,7 +386,7 @@ public synchronized BackupRegistry get() {
initTimestampMs = System.currentTimeMillis();
initRegistrySize = this.getApplications().size();
- registrySize.set(initRegistrySize);
+ registrySize = initRegistrySize;
logger.info("Discovery Client initialized at timestamp {} with initial instances count: {}",
initTimestampMs, initRegistrySize);
@@ -487,6 +475,12 @@ public synchronized BackupRegistry get() {
// finally, init the schedule tasks (e.g. cluster resolvers, heartbeat, instanceInfo replicator, fetch
initScheduledTasks();
+ try {
+ Monitors.registerObject(this);
+ } catch (Throwable e) {
+ logger.warn("Cannot register timers", e);
+ }
+
// This is a bit of hack to allow for existing code using DiscoveryManager.getInstance()
// to work with DI'd DiscoveryClient
DiscoveryManager.getInstance().setDiscoveryClient(this);
@@ -494,7 +488,7 @@ public synchronized BackupRegistry get() {
initTimestampMs = System.currentTimeMillis();
initRegistrySize = this.getApplications().size();
- registrySize.set(initRegistrySize);
+ registrySize = initRegistrySize;
logger.info("Discovery Client initialized at timestamp {} with initial instances count: {}",
initTimestampMs, initRegistrySize);
}
@@ -958,6 +952,11 @@ public synchronized void shutdown() {
eurekaTransport.shutdown();
}
+ heartbeatStalenessMonitor.shutdown();
+ registryStalenessMonitor.shutdown();
+
+ Monitors.unregisterObject(this);
+
logger.info("Completed shut down of DiscoveryClient");
}
}
@@ -991,7 +990,7 @@ void unregister() {
* @return true if the registry was fetched
*/
private boolean fetchRegistry(boolean forceFullRegistryFetch) {
- long monotonicTime = ServoUtil.time(FETCH_REGISTRY_TIMER);
+ Stopwatch tracer = FETCH_REGISTRY_TIMER.start();
try {
// If the delta is disabled or if it is the first time, get all
@@ -1023,7 +1022,9 @@ private boolean fetchRegistry(boolean forceFullRegistryFetch) {
appPathIdentifier, clientConfig.getRegistryFetchIntervalSeconds(), e.getMessage(), ExceptionUtils.getStackTrace(e));
return false;
} finally {
- ServoUtil.record(FETCH_REGISTRY_TIMER, monotonicTime);
+ if (tracer != null) {
+ tracer.stop();
+ }
}
// Notify about cache refresh before updating the instance remote status
@@ -1529,7 +1530,7 @@ void refreshRegistry() {
boolean success = fetchRegistry(remoteRegionsModified);
if (success) {
- registrySize.set(localRegionApps.get().size());
+ registrySize = localRegionApps.get().size();
lastSuccessfulRegistryFetchTimestamp = System.currentTimeMillis();
}
@@ -1729,6 +1730,8 @@ public long getLastSuccessfulRegistryFetchTimePeriod() {
: System.currentTimeMillis() - lastSuccessfulRegistryFetchTimestamp;
}
+ @com.netflix.servo.annotations.Monitor(name = METRIC_REGISTRATION_PREFIX + "lastSuccessfulHeartbeatTimePeriod",
+ description = "How much time has passed from last successful heartbeat", type = DataSourceType.GAUGE)
private long getLastSuccessfulHeartbeatTimePeriodInternal() {
final long delay = (!clientConfig.shouldRegisterWithEureka() || isShutdown.get())
? 0
@@ -1739,6 +1742,8 @@ private long getLastSuccessfulHeartbeatTimePeriodInternal() {
}
// for metrics only
+ @com.netflix.servo.annotations.Monitor(name = METRIC_REGISTRY_PREFIX + "lastSuccessfulRegistryFetchTimePeriod",
+ description = "How much time has passed from last successful local registry update", type = DataSourceType.GAUGE)
private long getLastSuccessfulRegistryFetchTimePeriodInternal() {
final long delay = (!clientConfig.shouldFetchRegistry() || isShutdown.get())
? 0
@@ -1748,6 +1753,13 @@ private long getLastSuccessfulRegistryFetchTimePeriodInternal() {
return delay;
}
+ @com.netflix.servo.annotations.Monitor(name = METRIC_REGISTRY_PREFIX + "localRegistrySize",
+ description = "Count of instances in the local registry", type = DataSourceType.GAUGE)
+ public int localRegistrySize() {
+ return registrySize;
+ }
+
+
private long computeStalenessMonitorDelay(long delay) {
if (delay < 0) {
return System.currentTimeMillis() - initTimestampMs;
@@ -1782,7 +1794,7 @@ public long initTimestampMs() {
}
public int localRegistrySize() {
- return registrySize.get();
+ return registrySize;
}
public long lastSuccessfulRegistryFetchTimestampMs() {
diff --git a/eureka-client/src/main/java/com/netflix/discovery/TimedSupervisorTask.java b/eureka-client/src/main/java/com/netflix/discovery/TimedSupervisorTask.java
index b088bb2ded..a2733fae1b 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/TimedSupervisorTask.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/TimedSupervisorTask.java
@@ -1,9 +1,5 @@
package com.netflix.discovery;
-import com.netflix.spectator.api.Counter;
-import com.netflix.spectator.api.Registry;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.patterns.PolledMeter;
import java.util.TimerTask;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
@@ -13,6 +9,10 @@
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicLong;
+import com.netflix.servo.monitor.Counter;
+import com.netflix.servo.monitor.LongGauge;
+import com.netflix.servo.monitor.MonitorConfig;
+import com.netflix.servo.monitor.Monitors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,7 +29,7 @@ public class TimedSupervisorTask extends TimerTask {
private final Counter timeoutCounter;
private final Counter rejectedCounter;
private final Counter throwableCounter;
- private final AtomicLong threadPoolLevelGauge;
+ private final LongGauge threadPoolLevelGauge;
private final String name;
private final ScheduledExecutorService scheduler;
@@ -51,12 +51,12 @@ public TimedSupervisorTask(String name, ScheduledExecutorService scheduler, Thre
this.maxDelay = timeoutMillis * expBackOffBound;
// Initialize the counters and register.
- final Registry registry = Spectator.globalRegistry();
- successCounter = registry.counter("success");
- timeoutCounter = registry.counter("timeouts");
- rejectedCounter = registry.counter("rejectedExecutions");
- throwableCounter = registry.counter("throwables");
- threadPoolLevelGauge = PolledMeter.using(registry).withName("threadPoolUsed").monitorValue(new AtomicLong());
+ successCounter = Monitors.newCounter("success");
+ timeoutCounter = Monitors.newCounter("timeouts");
+ rejectedCounter = Monitors.newCounter("rejectedExecutions");
+ throwableCounter = Monitors.newCounter("throwables");
+ threadPoolLevelGauge = new LongGauge(MonitorConfig.builder("threadPoolUsed").build());
+ Monitors.registerObject(name, this);
}
@Override
@@ -106,6 +106,7 @@ public void run() {
@Override
public boolean cancel() {
+ Monitors.unregisterObject(name, this);
return super.cancel();
}
}
\ No newline at end of file
diff --git a/eureka-client/src/main/java/com/netflix/discovery/converters/Converters.java b/eureka-client/src/main/java/com/netflix/discovery/converters/Converters.java
index 5a786ae550..6cb0ad0b44 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/converters/Converters.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/converters/Converters.java
@@ -16,8 +16,6 @@
package com.netflix.discovery.converters;
-import com.netflix.spectator.api.Counter;
-import com.netflix.spectator.api.Spectator;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -37,6 +35,8 @@
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import com.netflix.discovery.util.StringCache;
+import com.netflix.servo.monitor.Counter;
+import com.netflix.servo.monitor.Monitors;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
@@ -73,7 +73,7 @@ public final class Converters {
private static final Logger logger = LoggerFactory.getLogger(Converters.class);
- private static final Counter UNMARSHALL_ERROR_COUNTER = Spectator.globalRegistry().counter(UNMARSHAL_ERROR);
+ private static final Counter UNMARSHALL_ERROR_COUNTER = Monitors.newCounter(UNMARSHAL_ERROR);
/**
* Serialize/deserialize {@link Applications} object types.
diff --git a/eureka-client/src/main/java/com/netflix/discovery/shared/NamedConnectionPool.java b/eureka-client/src/main/java/com/netflix/discovery/shared/NamedConnectionPool.java
index fbe77498ab..2dad0422bf 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/shared/NamedConnectionPool.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/shared/NamedConnectionPool.java
@@ -1,14 +1,14 @@
package com.netflix.discovery.shared;
-import com.netflix.discovery.util.ServoUtil;
-import com.netflix.spectator.api.Counter;
-import com.netflix.spectator.api.Registry;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.Timer;
-import com.netflix.spectator.api.patterns.PolledMeter;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Preconditions;
+import com.netflix.servo.annotations.DataSourceType;
+import com.netflix.servo.annotations.Monitor;
+import com.netflix.servo.monitor.Counter;
+import com.netflix.servo.monitor.Monitors;
+import com.netflix.servo.monitor.Stopwatch;
+import com.netflix.servo.monitor.Timer;
import org.apache.http.conn.ClientConnectionOperator;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.params.ConnPerRoute;
@@ -76,17 +76,15 @@ public NamedConnectionPool(String name, ClientConnectionOperator operator,
void initMonitors(String name) {
Preconditions.checkNotNull(name);
- final Registry registry = Spectator.globalRegistry();
- freeEntryCounter = registry.counter(name + "_Reuse");
- createEntryCounter = registry.counter(name + "_CreateNew");
- requestCounter = registry.counter(name + "_Request");
- releaseCounter = registry.counter(name + "_Release");
- deleteCounter = registry.counter(name + "_Delete");
- requestTimer = registry.timer(name + "_RequestConnectionTimer");
- creationTimer = registry.timer(name + "_CreateConnectionTimer");
- PolledMeter.using(registry).withName("connectionCount")
- .monitorValue(this, NamedConnectionPool::getConnectionsInPool);
+ freeEntryCounter = Monitors.newCounter(name + "_Reuse");
+ createEntryCounter = Monitors.newCounter(name + "_CreateNew");
+ requestCounter = Monitors.newCounter(name + "_Request");
+ releaseCounter = Monitors.newCounter(name + "_Release");
+ deleteCounter = Monitors.newCounter(name + "_Delete");
+ requestTimer = Monitors.newTimer(name + "_RequestConnectionTimer", TimeUnit.MILLISECONDS);
+ creationTimer = Monitors.newTimer(name + "_CreateConnectionTimer", TimeUnit.MILLISECONDS);
this.name = name;
+ Monitors.registerObject(name, this);
}
@Override
@@ -108,11 +106,11 @@ protected BasicPoolEntry getFreeEntry(RouteSpecificPool rospl, Object state) {
protected BasicPoolEntry createEntry(RouteSpecificPool rospl,
ClientConnectionOperator op) {
createEntryCounter.increment();
- long monotonicTime = ServoUtil.time(creationTimer);
+ Stopwatch stopWatch = creationTimer.start();
try {
return super.createEntry(rospl, op);
} finally {
- ServoUtil.record(creationTimer, monotonicTime);
+ stopWatch.stop();
}
}
@@ -120,11 +118,11 @@ protected BasicPoolEntry createEntry(RouteSpecificPool rospl,
protected BasicPoolEntry getEntryBlocking(HttpRoute route, Object state,
long timeout, TimeUnit tunit, WaitingThreadAborter aborter)
throws ConnectionPoolTimeoutException, InterruptedException {
- long monotonicTime = ServoUtil.time(requestTimer);
+ Stopwatch stopWatch = requestTimer.start();
try {
return super.getEntryBlocking(route, state, timeout, tunit, aborter);
} finally {
- ServoUtil.record(requestTimer, monotonicTime);
+ stopWatch.stop();
}
}
@@ -142,27 +140,35 @@ protected void deleteEntry(BasicPoolEntry entry) {
}
public final long getFreeEntryCount() {
- return freeEntryCounter.count();
+ return freeEntryCounter.getValue().longValue();
}
public final long getCreatedEntryCount() {
- return createEntryCounter.count();
+ return createEntryCounter.getValue().longValue();
}
public final long getRequestsCount() {
- return requestCounter.count();
+ return requestCounter.getValue().longValue();
}
public final long getReleaseCount() {
- return releaseCounter.count();
+ return releaseCounter.getValue().longValue();
}
public final long getDeleteCount() {
- return deleteCounter.count();
+ return deleteCounter.getValue().longValue();
+ }
+
+ @Monitor(name = "connectionCount", type = DataSourceType.GAUGE)
+ public int getConnectionCount() {
+ return this.getConnectionsInPool();
}
@Override
public void shutdown() {
super.shutdown();
+ if(Monitors.isObjectRegistered(name, this)) {
+ Monitors.unregisterObject(name, this);
+ }
}
}
diff --git a/eureka-client/src/main/java/com/netflix/discovery/shared/resolver/AsyncResolver.java b/eureka-client/src/main/java/com/netflix/discovery/shared/resolver/AsyncResolver.java
index d863440b89..1acbb8d159 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/shared/resolver/AsyncResolver.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/shared/resolver/AsyncResolver.java
@@ -2,9 +2,9 @@
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.netflix.discovery.TimedSupervisorTask;
-import com.netflix.spectator.api.Registry;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.patterns.PolledMeter;
+import com.netflix.servo.annotations.DataSourceType;
+import com.netflix.servo.annotations.Monitor;
+import com.netflix.servo.monitor.Monitors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -107,11 +107,6 @@ public AsyncResolver(String name,
this.refreshIntervalMs = refreshIntervalMs;
this.warmUpTimeoutMs = warmUpTimeoutMs;
- final Registry registry = Spectator.globalRegistry();
- PolledMeter.using(registry)
- .withName(METRIC_RESOLVER_PREFIX + "lastLoadTimestamp")
- .monitorValue(this, AsyncResolver::getLastLoadTimestamp);
-
this.executorService = Executors.newScheduledThreadPool(1,
new ThreadFactoryBuilder()
.setNameFormat("AsyncResolver-" + name + "-%d")
@@ -138,13 +133,14 @@ public AsyncResolver(String name,
);
this.resultsRef = new AtomicReference<>(initialValue);
- PolledMeter.using(registry)
- .withName(METRIC_RESOLVER_PREFIX + "endpointsSize")
- .monitorValue(this, AsyncResolver::getEndpointsSize);
+ Monitors.registerObject(name, this);
}
@Override
public void shutdown() {
+ if(Monitors.isObjectRegistered(name, this)) {
+ Monitors.unregisterObject(name, this);
+ }
executorService.shutdownNow();
threadPoolExecutor.shutdownNow();
backgroundTask.cancel();
@@ -192,10 +188,14 @@ public List getClusterEndpoints() {
backgroundTask, delay, TimeUnit.MILLISECONDS);
}
+ @Monitor(name = METRIC_RESOLVER_PREFIX + "lastLoadTimestamp",
+ description = "How much time has passed from last successful async load", type = DataSourceType.GAUGE)
public long getLastLoadTimestamp() {
return lastLoadTimestamp < 0 ? 0 : System.currentTimeMillis() - lastLoadTimestamp;
}
+ @Monitor(name = METRIC_RESOLVER_PREFIX + "endpointsSize",
+ description = "How many records are the in the endpoints ref", type = DataSourceType.GAUGE)
public long getEndpointsSize() {
return resultsRef.get().size(); // return directly from the ref and not the method so as to not trigger warming
}
diff --git a/eureka-client/src/main/java/com/netflix/discovery/shared/resolver/ReloadingClusterResolver.java b/eureka-client/src/main/java/com/netflix/discovery/shared/resolver/ReloadingClusterResolver.java
index 3c696a1a79..ed1ce33f90 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/shared/resolver/ReloadingClusterResolver.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/shared/resolver/ReloadingClusterResolver.java
@@ -16,11 +16,12 @@
package com.netflix.discovery.shared.resolver;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.patterns.PolledMeter;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
+import com.netflix.servo.annotations.DataSourceType;
+import com.netflix.servo.annotations.Monitor;
+import com.netflix.servo.monitor.Monitors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -73,9 +74,12 @@ public ReloadingClusterResolver(final ClusterResolverFactory factory, final l
logger.info("Initiated with delegate resolver of type {}; next reload in {}[sec]. Loaded endpoints={}",
delegateRef.get().getClass(), currentReloadIntervalMs / 1000, clusterEndpoints);
}
- PolledMeter.using(Spectator.globalRegistry())
- .withName(METRIC_RESOLVER_PREFIX + "lastReloadTimestamp")
- .monitorValue(this, ReloadingClusterResolver::getLastReloadTimestamp);
+
+ try {
+ Monitors.registerObject(this);
+ } catch (Throwable e) {
+ logger.warn("Cannot register metrics", e);
+ }
}
@Override
@@ -129,6 +133,8 @@ private ClusterResolver reload() {
return newDelegate;
}
+ @Monitor(name = METRIC_RESOLVER_PREFIX + "lastReloadTimestamp",
+ description = "How much time has passed from last successful cluster configuration resolve", type = DataSourceType.GAUGE)
public long getLastReloadTimestamp() {
return lastReloadTimestamp < 0 ? 0 : System.currentTimeMillis() - lastReloadTimestamp;
}
diff --git a/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/MetricsCollectingEurekaHttpClient.java b/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/MetricsCollectingEurekaHttpClient.java
index 2a7c17e94f..3695c7751b 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/MetricsCollectingEurekaHttpClient.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/MetricsCollectingEurekaHttpClient.java
@@ -16,13 +16,9 @@
package com.netflix.discovery.shared.transport.decorator;
-import com.netflix.discovery.util.ServoUtil;
-import com.netflix.spectator.api.Counter;
-import com.netflix.spectator.api.Registry;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.Timer;
import java.util.EnumMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import com.netflix.discovery.EurekaClientNames;
import com.netflix.discovery.shared.resolver.EurekaEndpoint;
@@ -32,6 +28,13 @@
import com.netflix.discovery.shared.transport.TransportClientFactory;
import com.netflix.discovery.shared.transport.decorator.MetricsCollectingEurekaHttpClient.EurekaHttpClientRequestMetrics.Status;
import com.netflix.discovery.util.ExceptionsMetric;
+import com.netflix.discovery.util.ServoUtil;
+import com.netflix.servo.monitor.BasicCounter;
+import com.netflix.servo.monitor.BasicTimer;
+import com.netflix.servo.monitor.Counter;
+import com.netflix.servo.monitor.MonitorConfig;
+import com.netflix.servo.monitor.Stopwatch;
+import com.netflix.servo.monitor.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -65,7 +68,7 @@ private MetricsCollectingEurekaHttpClient(EurekaHttpClient delegate,
@Override
protected EurekaHttpResponse execute(RequestExecutor requestExecutor) {
EurekaHttpClientRequestMetrics requestMetrics = metricsByRequestType.get(requestExecutor.getRequestType());
- long monotonicTime = ServoUtil.time(requestMetrics.latencyTimer);
+ Stopwatch stopwatch = requestMetrics.latencyTimer.start();
try {
EurekaHttpResponse httpResponse = requestExecutor.execute(delegate);
requestMetrics.countersByStatus.get(mappedStatus(httpResponse)).increment();
@@ -75,13 +78,14 @@ protected EurekaHttpResponse execute(RequestExecutor requestExecutor)
exceptionsMetric.count(e);
throw e;
} finally {
- ServoUtil.record(requestMetrics.latencyTimer, monotonicTime);
+ stopwatch.stop();
}
}
@Override
public void shutdown() {
if (shutdownMetrics) {
+ shutdownMetrics(metricsByRequestType);
exceptionsMetric.shutdown();
}
}
@@ -102,6 +106,7 @@ public EurekaHttpClient newClient() {
@Override
public void shutdown() {
+ shutdownMetrics(metricsByRequestType);
exceptionMetrics.shutdown();
}
};
@@ -123,6 +128,7 @@ public EurekaHttpClient newClient(EurekaEndpoint endpoint) {
@Override
public void shutdown() {
+ shutdownMetrics(metricsByRequestType);
exceptionMetrics.shutdown();
}
};
@@ -140,6 +146,12 @@ private static Map initializeMetric
return result;
}
+ private static void shutdownMetrics(Map metricsByRequestType) {
+ for (EurekaHttpClientRequestMetrics metrics : metricsByRequestType.values()) {
+ metrics.shutdown();
+ }
+ }
+
private static Status mappedStatus(EurekaHttpResponse> httpResponse) {
int category = httpResponse.getStatusCode() / 100;
switch (category) {
@@ -168,26 +180,41 @@ enum Status {x100, x200, x300, x400, x500, Unknown}
EurekaHttpClientRequestMetrics(String resourceName) {
this.countersByStatus = createStatusCounters(resourceName);
- final Registry registry = Spectator.globalRegistry();
- latencyTimer = registry.timer(EurekaClientNames.METRIC_TRANSPORT_PREFIX + "latency",
- "id", resourceName,
- "class", MetricsCollectingEurekaHttpClient.class.getSimpleName());
+ latencyTimer = new BasicTimer(
+ MonitorConfig.builder(EurekaClientNames.METRIC_TRANSPORT_PREFIX + "latency")
+ .withTag("id", resourceName)
+ .withTag("class", MetricsCollectingEurekaHttpClient.class.getSimpleName())
+ .build(),
+ TimeUnit.MILLISECONDS
+ );
+ ServoUtil.register(latencyTimer);
+
+ this.connectionErrors = new BasicCounter(
+ MonitorConfig.builder(EurekaClientNames.METRIC_TRANSPORT_PREFIX + "connectionErrors")
+ .withTag("id", resourceName)
+ .withTag("class", MetricsCollectingEurekaHttpClient.class.getSimpleName())
+ .build()
+ );
+ ServoUtil.register(connectionErrors);
+ }
- this.connectionErrors = registry.counter(
- EurekaClientNames.METRIC_TRANSPORT_PREFIX + "connectionErrors"
- ,"id", resourceName
- ,"class", MetricsCollectingEurekaHttpClient.class.getSimpleName());
+ void shutdown() {
+ ServoUtil.unregister(latencyTimer, connectionErrors);
+ ServoUtil.unregister(countersByStatus.values());
}
private static Map createStatusCounters(String resourceName) {
Map result = new EnumMap<>(Status.class);
for (Status status : Status.values()) {
- Counter counter = Spectator.globalRegistry().counter(
- EurekaClientNames.METRIC_TRANSPORT_PREFIX + "request"
- ,"id", resourceName
- ,"class", MetricsCollectingEurekaHttpClient.class.getSimpleName()
- ,"status", status.name());
+ BasicCounter counter = new BasicCounter(
+ MonitorConfig.builder(EurekaClientNames.METRIC_TRANSPORT_PREFIX + "request")
+ .withTag("id", resourceName)
+ .withTag("class", MetricsCollectingEurekaHttpClient.class.getSimpleName())
+ .withTag("status", status.name())
+ .build()
+ );
+ ServoUtil.register(counter);
result.put(status, counter);
}
diff --git a/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/RetryableEurekaHttpClient.java b/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/RetryableEurekaHttpClient.java
index 1df3e5af2c..92abccc575 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/RetryableEurekaHttpClient.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/RetryableEurekaHttpClient.java
@@ -16,8 +16,6 @@
package com.netflix.discovery.shared.transport.decorator;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.patterns.PolledMeter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -33,6 +31,9 @@
import com.netflix.discovery.shared.transport.TransportClientFactory;
import com.netflix.discovery.shared.transport.TransportException;
import com.netflix.discovery.shared.transport.TransportUtils;
+import com.netflix.servo.annotations.DataSourceType;
+import com.netflix.servo.annotations.Monitor;
+import com.netflix.servo.monitor.Monitors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -68,9 +69,7 @@ public class RetryableEurekaHttpClient extends EurekaHttpClientDecorator {
private final AtomicReference delegate = new AtomicReference<>();
- private final Set quarantineSet = PolledMeter.using(Spectator.globalRegistry())
- .withName(METRIC_TRANSPORT_PREFIX + "quarantineSize")
- .monitorSize(new ConcurrentSkipListSet<>());
+ private final Set quarantineSet = new ConcurrentSkipListSet<>();
public RetryableEurekaHttpClient(String name,
EurekaTransportConfig transportConfig,
@@ -84,11 +83,15 @@ public RetryableEurekaHttpClient(String name,
this.clientFactory = clientFactory;
this.serverStatusEvaluator = serverStatusEvaluator;
this.numberOfRetries = numberOfRetries;
+ Monitors.registerObject(name, this);
}
@Override
public void shutdown() {
TransportUtils.shutdown(delegate.get());
+ if(Monitors.isObjectRegistered(name, this)) {
+ Monitors.unregisterObject(name, this);
+ }
}
@Override
@@ -182,4 +185,10 @@ private List getHostCandidates() {
return candidateHosts;
}
+
+ @Monitor(name = METRIC_TRANSPORT_PREFIX + "quarantineSize",
+ description = "number of servers quarantined", type = DataSourceType.GAUGE)
+ public long getQuarantineSetSize() {
+ return quarantineSet.size();
+ }
}
diff --git a/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/SessionedEurekaHttpClient.java b/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/SessionedEurekaHttpClient.java
index 30b99bf9ba..550e675cbd 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/SessionedEurekaHttpClient.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/shared/transport/decorator/SessionedEurekaHttpClient.java
@@ -16,8 +16,6 @@
package com.netflix.discovery.shared.transport.decorator;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.patterns.PolledMeter;
import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;
@@ -25,6 +23,9 @@
import com.netflix.discovery.shared.transport.EurekaHttpClientFactory;
import com.netflix.discovery.shared.transport.EurekaHttpResponse;
import com.netflix.discovery.shared.transport.TransportUtils;
+import com.netflix.servo.annotations.DataSourceType;
+import com.netflix.servo.annotations.Monitor;
+import com.netflix.servo.monitor.Monitors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,9 +56,7 @@ public SessionedEurekaHttpClient(String name, EurekaHttpClientFactory clientFact
this.clientFactory = clientFactory;
this.sessionDurationMs = sessionDurationMs;
this.currentSessionDurationMs = randomizeSessionDuration(sessionDurationMs);
- PolledMeter.using(Spectator.globalRegistry())
- .withName(METRIC_TRANSPORT_PREFIX + "currentSessionDuration")
- .monitorValue(this, SessionedEurekaHttpClient::getCurrentSessionDuration);
+ Monitors.registerObject(name, this);
}
@Override
@@ -80,6 +79,9 @@ protected EurekaHttpResponse execute(RequestExecutor requestExecutor)
@Override
public void shutdown() {
+ if(Monitors.isObjectRegistered(name, this)) {
+ Monitors.unregisterObject(name, this);
+ }
TransportUtils.shutdown(eurekaHttpClientRef.getAndSet(null));
}
@@ -91,6 +93,8 @@ protected long randomizeSessionDuration(long sessionDurationMs) {
return sessionDurationMs + delta;
}
+ @Monitor(name = METRIC_TRANSPORT_PREFIX + "currentSessionDuration",
+ description = "Duration of the current session", type = DataSourceType.GAUGE)
public long getCurrentSessionDuration() {
return lastReconnectTimeStamp < 0 ? 0 : System.currentTimeMillis() - lastReconnectTimeStamp;
}
diff --git a/eureka-client/src/main/java/com/netflix/discovery/shared/transport/jersey/ApacheHttpClientConnectionCleaner.java b/eureka-client/src/main/java/com/netflix/discovery/shared/transport/jersey/ApacheHttpClientConnectionCleaner.java
index e4310e5851..a56d736471 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/shared/transport/jersey/ApacheHttpClientConnectionCleaner.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/shared/transport/jersey/ApacheHttpClientConnectionCleaner.java
@@ -16,16 +16,18 @@
package com.netflix.discovery.shared.transport.jersey;
-import com.netflix.spectator.api.Counter;
-import com.netflix.spectator.api.Registry;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.Timer;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import com.netflix.servo.monitor.BasicCounter;
+import com.netflix.servo.monitor.BasicTimer;
+import com.netflix.servo.monitor.Counter;
+import com.netflix.servo.monitor.MonitorConfig;
+import com.netflix.servo.monitor.Monitors;
+import com.netflix.servo.monitor.Stopwatch;
import com.sun.jersey.client.apache4.ApacheHttpClient4;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,7 +57,7 @@ public Thread newThread(Runnable r) {
private final ApacheHttpClient4 apacheHttpClient;
- private final Timer executionTimeStats;
+ private final BasicTimer executionTimeStats;
private final Counter cleanupFailed;
public ApacheHttpClientConnectionCleaner(ApacheHttpClient4 apacheHttpClient, final long connectionIdleTimeout) {
@@ -72,26 +74,35 @@ public void run() {
TimeUnit.MILLISECONDS
);
- final Registry registry = Spectator.globalRegistry();
- executionTimeStats = registry.timer("Eureka-Connection-Cleaner-Time");
- cleanupFailed = registry.counter("Eureka-Connection-Cleaner-Failure");
+ MonitorConfig.Builder monitorConfigBuilder = MonitorConfig.builder("Eureka-Connection-Cleaner-Time");
+ executionTimeStats = new BasicTimer(monitorConfigBuilder.build());
+ cleanupFailed = new BasicCounter(MonitorConfig.builder("Eureka-Connection-Cleaner-Failure").build());
+ try {
+ Monitors.registerObject(this);
+ } catch (Exception e) {
+ logger.error("Unable to register with servo.", e);
+ }
}
public void shutdown() {
cleanIdle(0);
eurekaConnCleaner.shutdown();
+ Monitors.unregisterObject(this);
}
public void cleanIdle(long delayMs) {
- executionTimeStats.recordRunnable(() -> {
- try {
- apacheHttpClient.getClientHandler().getHttpClient()
+ Stopwatch start = executionTimeStats.start();
+ try {
+ apacheHttpClient.getClientHandler().getHttpClient()
.getConnectionManager()
.closeIdleConnections(delayMs, TimeUnit.SECONDS);
- } catch (Throwable e) {
- logger.error("Cannot clean connections", e);
- cleanupFailed.increment();
+ } catch (Throwable e) {
+ logger.error("Cannot clean connections", e);
+ cleanupFailed.increment();
+ } finally {
+ if (null != start) {
+ start.stop();
}
- });
+ }
}
}
diff --git a/eureka-client/src/main/java/com/netflix/discovery/util/ExceptionsMetric.java b/eureka-client/src/main/java/com/netflix/discovery/util/ExceptionsMetric.java
index 5fc0e48ee1..0af818aa5b 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/util/ExceptionsMetric.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/util/ExceptionsMetric.java
@@ -16,10 +16,14 @@
package com.netflix.discovery.util;
-import com.netflix.spectator.api.Counter;
-import com.netflix.spectator.api.Spectator;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import com.netflix.servo.DefaultMonitorRegistry;
+import com.netflix.servo.monitor.BasicCounter;
+import com.netflix.servo.monitor.Counter;
+import com.netflix.servo.monitor.MonitorConfig;
+
/**
* Counters for exceptions.
*
@@ -40,17 +44,20 @@ public void count(Throwable ex) {
}
public void shutdown() {
-
+ ServoUtil.unregister(exceptionCounters.values());
}
private Counter getOrCreateCounter(String exceptionName) {
Counter counter = exceptionCounters.get(exceptionName);
- if (counter != null) {
- return counter;
+ if (counter == null) {
+ counter = new BasicCounter(MonitorConfig.builder(name).withTag("id", exceptionName).build());
+ if (exceptionCounters.putIfAbsent(exceptionName, counter) == null) {
+ DefaultMonitorRegistry.getInstance().register(counter);
+ } else {
+ counter = exceptionCounters.get(exceptionName);
+ }
}
- return exceptionCounters.computeIfAbsent(exceptionName, s ->
- Spectator.globalRegistry().counter(
- name, "id", exceptionName));
+ return counter;
}
private static String extractName(Throwable ex) {
diff --git a/eureka-client/src/main/java/com/netflix/discovery/util/ServoUtil.java b/eureka-client/src/main/java/com/netflix/discovery/util/ServoUtil.java
index d2c90cc5db..05a86f014a 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/util/ServoUtil.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/util/ServoUtil.java
@@ -16,23 +16,54 @@
package com.netflix.discovery.util;
-import com.netflix.spectator.api.Timer;
-import java.util.concurrent.TimeUnit;
-import javax.annotation.Nonnull;
+import java.util.Collection;
+
+import com.netflix.servo.DefaultMonitorRegistry;
+import com.netflix.servo.monitor.Monitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+/**
+ * @author Tomasz Bak
+ */
public final class ServoUtil {
- private ServoUtil() {
- }
+ private static final Logger logger = LoggerFactory.getLogger(ServoUtil.class);
+
+ private ServoUtil() {
+ }
+
+ public static boolean register(Monitor monitor) {
+ try {
+ DefaultMonitorRegistry.getInstance().register(monitor);
+ } catch (Exception e) {
+ logger.warn("Cannot register monitor {}", monitor.getConfig().getName());
+ if (logger.isDebugEnabled()) {
+ logger.debug(e.getMessage(), e);
+ }
+ return false;
+ }
+ return true;
+ }
- public static long time(@Nonnull Timer timer) {
- return timer.clock().monotonicTime();
- }
+ public static void unregister(Monitor monitor) {
+ if (monitor != null) {
+ try {
+ DefaultMonitorRegistry.getInstance().unregister(monitor);
+ } catch (Exception ignore) {
+ }
+ }
+ }
- public static void record(@Nonnull Timer timer, long startTime) {
- timer.record(time(timer) - startTime, TimeUnit.NANOSECONDS);
- }
+ public static void unregister(Monitor... monitors) {
+ for (Monitor monitor : monitors) {
+ unregister(monitor);
+ }
+ }
+ public static void unregister(Collection monitors) {
+ for (M monitor : monitors) {
+ unregister(monitor);
+ }
+ }
}
diff --git a/eureka-client/src/main/java/com/netflix/discovery/util/ThresholdLevelsMetric.java b/eureka-client/src/main/java/com/netflix/discovery/util/ThresholdLevelsMetric.java
index 4669b85d70..c3bcbfa73d 100644
--- a/eureka-client/src/main/java/com/netflix/discovery/util/ThresholdLevelsMetric.java
+++ b/eureka-client/src/main/java/com/netflix/discovery/util/ThresholdLevelsMetric.java
@@ -16,9 +16,11 @@
package com.netflix.discovery.util;
-import com.netflix.spectator.api.Spectator;
-import com.netflix.spectator.api.patterns.PolledMeter;
-import java.util.concurrent.atomic.AtomicLong;
+import com.netflix.servo.DefaultMonitorRegistry;
+import com.netflix.servo.monitor.LongGauge;
+import com.netflix.servo.monitor.MonitorConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A collection of gauges that represent different threshold levels over which measurement is mapped to.
@@ -30,27 +32,28 @@
*/
public class ThresholdLevelsMetric {
- public static final ThresholdLevelsMetric NO_OP_METRIC = new ThresholdLevelsMetric() {
- @Override
- public void update(long delayMs) {
- }
- };
+ public static final ThresholdLevelsMetric NO_OP_METRIC = new NoOpThresholdLevelMetric();
- private final long[] levels;
- private final AtomicLong[] gauges;
+ private static final Logger logger = LoggerFactory.getLogger(ThresholdLevelsMetric.class);
- public ThresholdLevelsMetric() {
- levels = null;
- gauges = null;
- }
+ private final long[] levels;
+ private final LongGauge[] gauges;
public ThresholdLevelsMetric(Object owner, String prefix, long[] levels) {
this.levels = levels;
- this.gauges = new AtomicLong[levels.length];
+ this.gauges = new LongGauge[levels.length];
for (int i = 0; i < levels.length; i++) {
String name = prefix + String.format("%05d", levels[i]);
- gauges[i] = PolledMeter.using(Spectator.globalRegistry()).withName(name)
- .withTag("class", owner.getClass().getName()).monitorValue(new AtomicLong());
+ MonitorConfig config = new MonitorConfig.Builder(name)
+ .withTag("class", owner.getClass().getName())
+ .build();
+ gauges[i] = new LongGauge(config);
+
+ try {
+ DefaultMonitorRegistry.getInstance().register(gauges[i]);
+ } catch (Throwable e) {
+ logger.warn("Cannot register metric {}", name, e);
+ }
}
}
@@ -76,4 +79,26 @@ public void update(long delayMs) {
}
}
}
+
+ public void shutdown() {
+ for (LongGauge gauge : gauges) {
+ try {
+ DefaultMonitorRegistry.getInstance().unregister(gauge);
+ } catch (Throwable ignore) {
+ }
+ }
+ }
+
+ public static class NoOpThresholdLevelMetric extends ThresholdLevelsMetric {
+
+ public NoOpThresholdLevelMetric() {
+ super(null, null, new long[]{});
+ }
+
+ public void update(long delayMs) {
+ }
+
+ public void shutdown() {
+ }
+ }
}
diff --git a/eureka-client/src/test/java/com/netflix/discovery/shared/transport/jersey/UnexpectedContentTypeTest.java b/eureka-client/src/test/java/com/netflix/discovery/shared/transport/jersey/UnexpectedContentTypeTest.java
index eda5402c95..f29db25a52 100644
--- a/eureka-client/src/test/java/com/netflix/discovery/shared/transport/jersey/UnexpectedContentTypeTest.java
+++ b/eureka-client/src/test/java/com/netflix/discovery/shared/transport/jersey/UnexpectedContentTypeTest.java
@@ -7,7 +7,6 @@
import com.netflix.discovery.shared.transport.TransportClientFactory;
import org.junit.After;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@@ -48,7 +47,6 @@ public void setUp() throws Exception {
}
@Test
- @Ignore("failing in main branch")
public void testSendHeartBeatReceivesUnexpectedHtmlResponse() {
long lastDirtyTimestamp = System.currentTimeMillis();
String uuid = UUID.randomUUID().toString();
diff --git a/eureka-core/build.gradle b/eureka-core/build.gradle
index ca51cfbf19..32b69cfd63 100644
--- a/eureka-core/build.gradle
+++ b/eureka-core/build.gradle
@@ -9,7 +9,6 @@ dependencies {
compile "javax.servlet:servlet-api:${servletVersion}"
compile 'com.thoughtworks.xstream:xstream:1.4.19'
compile 'javax.ws.rs:jsr311-api:1.1.1'
- compile "com.netflix.servo:servo-core:0.12.21"
// These dependencies are marked 'compileOnly' in the client, but we need them always on the server
compile "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${jacksonVersion}"
diff --git a/eureka-core/src/test/java/com/netflix/eureka/registry/TimeConsumingInstanceRegistryTest.java b/eureka-core/src/test/java/com/netflix/eureka/registry/TimeConsumingInstanceRegistryTest.java
index 926435ac85..bf7dd1163c 100644
--- a/eureka-core/src/test/java/com/netflix/eureka/registry/TimeConsumingInstanceRegistryTest.java
+++ b/eureka-core/src/test/java/com/netflix/eureka/registry/TimeConsumingInstanceRegistryTest.java
@@ -9,9 +9,7 @@
import com.netflix.eureka.test.async.executor.AsyncSequentialExecutor;
import com.netflix.eureka.test.async.executor.SequentialEvents;
import com.netflix.eureka.test.async.executor.SingleEvent;
-import javax.inject.Inject;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
/**
@@ -69,7 +67,6 @@ public class TimeConsumingInstanceRegistryTest extends AbstractTester {
* Note that there is a thread retrieving and printing out registry status for debugging purpose.
*/
@Test
- @Ignore("NumOfRenewsPerMinThreshold should be updated to 256")
public void testLeaseExpirationAndUpdateRenewalThreshold() throws InterruptedException {
final int registeredInstanceCount = 50;
final int leaseDurationInSecs = 30;
diff --git a/eureka-test-utils/build.gradle b/eureka-test-utils/build.gradle
index 7954674a81..d6014f2360 100644
--- a/eureka-test-utils/build.gradle
+++ b/eureka-test-utils/build.gradle
@@ -2,5 +2,4 @@ dependencies {
compile project(':eureka-core')
compile "junit:junit:${junit_version}"
compile "org.mockito:mockito-core:${mockitoVersion}"
- compile "com.netflix.netflix-commons:netflix-eventbus:0.3.0"
}