Skip to content

Commit

Permalink
Merge pull request #198 from brharrington/static-registry-use-composite
Browse files Browse the repository at this point in the history
global registry is now a composite
  • Loading branch information
brharrington committed Aug 11, 2015
2 parents e1ba27c + 33825db commit 1a198c6
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* Maps calls to zero or more sub-registries. If zero then it will act similar to the noop
* registry. Otherwise activity will be sent to all registries that are part of the composite.
*/
final class CompositeRegistry implements Registry {
public final class CompositeRegistry implements Registry {

/**
* Id used for a meter storing all gauges registered with the composite. Since there is no
Expand Down Expand Up @@ -71,6 +71,11 @@ public void remove(Registry registry) {
registries.remove(registry);
}

/** Remove all registries from the composite. */
public void removeAll() {
registries.clear();
}

@Override public Clock clock() {
return clock;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public final class Spectator {

private static final ConfigMap CONFIG = newConfigMapUsingServiceLoader();

private static final ExtendedRegistry REGISTRY =
new ExtendedRegistry(newInstance(Config.registryClass()));
private static final CompositeRegistry COMPOSITE_REGISTRY = new CompositeRegistry(Clock.SYSTEM);
private static final ExtendedRegistry REGISTRY = new ExtendedRegistry(COMPOSITE_REGISTRY);

/**
* Create a new config map instance using {@link java.util.ServiceLoader}. If no implementations
Expand All @@ -58,7 +58,7 @@ static ConfigMap newConfigMapUsingServiceLoader() {
* Create a new registry instance using {@link java.util.ServiceLoader}. If no implementations
* are found the default will be used.
*/
static Registry newInstanceUsingServiceLoader() {
static void addRegistriesFromServiceLoader() {
final ClassLoader cl = pickClassLoader();
final ServiceLoader<Registry> loader = ServiceLoader.load(Registry.class, cl);
final Iterator<Registry> registryIterator = loader.iterator();
Expand All @@ -75,18 +75,16 @@ static Registry newInstanceUsingServiceLoader() {
}
}
if (rs.isEmpty()) {
return new DefaultRegistry();
COMPOSITE_REGISTRY.add(new DefaultRegistry());
} else {
CompositeRegistry composite = new CompositeRegistry(Clock.SYSTEM);
for (Registry r : rs) {
composite.add(r);
COMPOSITE_REGISTRY.add(r);
}
LOGGER.info("using registries found in classpath: {}", desc.toString());
return composite;
}
} else {
LOGGER.warn("no registry impl found in classpath, using default");
return new DefaultRegistry();
COMPOSITE_REGISTRY.add(new DefaultRegistry());
}
}

Expand All @@ -106,23 +104,25 @@ private static ClassLoader pickClassLoader() {
* Create a new registry instance using the class name specified by the system property
* {@code spectator.api.registryClass}. If no implementations are found the default will be used.
*/
static Registry newInstanceUsingClassName(String name) {
static void addRegistryUsingClassName(String name) {
try {
final Class<?> c = Class.forName(name);
return (Registry) c.newInstance();
COMPOSITE_REGISTRY.add((Registry) c.newInstance());
} catch (Exception e) {
final String msg = "failed to instantiate registry class '" + name
+ "', falling back to default implementation";
Throwables.propagate(new RuntimeException(msg, e));
return new DefaultRegistry();
COMPOSITE_REGISTRY.add(new DefaultRegistry());
}
}

/** Create a new instance of the registry. */
static Registry newInstance(String name) {
return Config.SERVICE_LOADER.equals(name)
? newInstanceUsingServiceLoader()
: newInstanceUsingClassName(name);
static void addRegistries(String name) {
if (Config.SERVICE_LOADER.equals(name)) {
addRegistriesFromServiceLoader();
} else {
addRegistryUsingClassName(name);
}
}

/**
Expand All @@ -133,19 +133,81 @@ public static ConfigMap config() {
}

/**
* Return the default global registry implementation. The implementation used will depend on the
* Setup the default global registry implementation. The implementation used will depend on the
* system property {@code spectator.api.registryClass}. If not set or set to
* {@code service-loader} the registry class will be determined by scanning the classpath using
* {@link java.util.ServiceLoader}. Otherwise an instance of the classname specified will be
* used. If a registry cannot be loaded the fallback is to use the {@link DefaultRegistry}.
* When {@code spectator.api.propagateWarnings} is set to {@code true} and an explicit class name
* is specified a {@link java.lang.RuntimeException} will be thrown if the specified class cannot
* be used.
*
* @deprecated This provides the legacy behavior if needed. It is preferred to setup a registry
* and inject. If the static
*/
@Deprecated
public static void initializeUsingServiceLoader() {
addRegistries(Config.registryClass());
}

/**
* Returns the global registry.
*
* @deprecated Use injection or {@link #globalRegistry()} instead.
*/
@Deprecated
public static ExtendedRegistry registry() {
return REGISTRY;
}

/**
* Returns the global composite registry. This method can be used for use-cases where it is
* necessary to get a static reference to a registry. It will not do anything unless other
* registries are added. Example:
*
* <pre>
* class Main {
* public static void main(String[] args) {
* // This is the preferred usage and works well with DI libraries like guice. Setup a
* // registry and pass it in as needed.
* Registry registry = new DefaultRegistry();
* (new Example1(registry)).start();
*
* // If it is desirable to get data from things using the global registry, then the
* // registry for the application can be added to the global context.
* Spectator.globalRegistry().add(registry);
* Example2 ex2 = new Example2();
* ex2.start();
*
* // If the lifecycle is not the same as the jvm, then the registry should be removed
* // when shutting down.
* ex2.onShutdown(() -> Spectator.globalRegistry().remove(registry));
* }
* }
*
* class Example1 {
* private final Counter c;
*
* Example1(Registry registry) {
* c = registry.counter("example1");
* }
* ...
* }
*
* class Example2 {
* private final Counter c;
*
* Example2() {
* c = Spectator.globalRegistry().counter("example1");
* }
* ...
* }
* </pre>
*/
public static CompositeRegistry globalRegistry() {
return COMPOSITE_REGISTRY;
}

private Spectator() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ public void testRegistry() {

@Test
public void testNewInstanceBadClass() {
Spectator.globalRegistry().removeAll();
System.setProperty("spectator.api.propagateWarnings", "false");
Assert.assertTrue(Spectator.newInstance("fubar") instanceof DefaultRegistry);
Spectator.addRegistries("fubar");
}

@Test(expected = RuntimeException.class)
public void testNewInstanceBadClassPropagate() {
System.setProperty("spectator.api.propagateWarnings", "true");
Spectator.newInstance("fubar");
Spectator.addRegistries("fubar");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,24 @@ public final class GcLogger {

// Max size of old generation memory pool
private static final AtomicLong MAX_DATA_SIZE =
Spectator.registry().gauge("jvm.gc.maxDataSize", new AtomicLong(0L));
Spectator.globalRegistry().gauge("jvm.gc.maxDataSize", new AtomicLong(0L));

// Size of old generation memory pool after a full GC
private static final AtomicLong LIVE_DATA_SIZE =
Spectator.registry().gauge("jvm.gc.liveDataSize", new AtomicLong(0L));
Spectator.globalRegistry().gauge("jvm.gc.liveDataSize", new AtomicLong(0L));

// Incremented for any positive increases in the size of the old generation memory pool
// before GC to after GC
private static final Counter PROMOTION_RATE =
Spectator.registry().counter("jvm.gc.promotionRate");
Spectator.globalRegistry().counter("jvm.gc.promotionRate");

// Incremented for the increase in the size of the young generation memory pool after one GC
// to before the next
private static final Counter ALLOCATION_RATE =
Spectator.registry().counter("jvm.gc.allocationRate");
Spectator.globalRegistry().counter("jvm.gc.allocationRate");

// Pause time due to GC event
private static final Id PAUSE_TIME = Spectator.registry().createId("jvm.gc.pause");
private static final Id PAUSE_TIME = Spectator.globalRegistry().createId("jvm.gc.pause");

private final long jvmStartTime;

Expand Down Expand Up @@ -200,7 +200,7 @@ private void processGcEvent(GarbageCollectionNotificationInfo info) {
Id eventId = PAUSE_TIME
.withTag("action", info.getGcAction())
.withTag("cause", info.getGcCause());
Timer timer = Spectator.registry().timer(eventId);
Timer timer = Spectator.globalRegistry().timer(eventId);
timer.record(info.getGcInfo().getDuration(), TimeUnit.MILLISECONDS);

// Update promotion and allocation counters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public static SpectatorAppender createAppender(
return null;
}

return new SpectatorAppender(Spectator.registry(), name, filter, layout, ignoreExceptions);
return new SpectatorAppender(Spectator.globalRegistry(), name, filter, layout, ignoreExceptions);
}

@Override public void start() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public final class BucketCounter implements DistributionSummary {
* Distribution summary that manages sub-counters based on the bucket function.
*/
public static BucketCounter get(Id id, BucketFunction f) {
return get(Spectator.registry(), id, f);
return get(Spectator.globalRegistry(), id, f);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public final class BucketDistributionSummary implements DistributionSummary {
* Distribution summary that manages sub-counters based on the bucket function.
*/
public static BucketDistributionSummary get(Id id, BucketFunction f) {
return get(Spectator.registry(), id, f);
return get(Spectator.globalRegistry(), id, f);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public final class BucketTimer implements Timer {
* Timer that manages sub-timers based on the bucket function.
*/
public static BucketTimer get(Id id, BucketFunction f) {
return get(Spectator.registry(), id, f);
return get(Spectator.globalRegistry(), id, f);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class DoubleDistributionSummary implements Meter {
* Distribution summary corresponding to the id.
*/
public static DoubleDistributionSummary get(Id id) {
return get(Spectator.registry(), id);
return get(Spectator.globalRegistry(), id);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class HttpLogEntry {
private static final Marker CLIENT = MarkerFactory.getMarker("http-client");
private static final Marker SERVER = MarkerFactory.getMarker("http-server");

private static final Registry REGISTRY = Spectator.registry();
private static final Registry REGISTRY = Spectator.globalRegistry();
private static final Id COMPLETE = REGISTRY.createId("http.req.complete");
private static final Id ATTEMPT = REGISTRY.createId("http.req.attempt");
private static final Id REQ_HEADER_SIZE = REGISTRY.createId("http.req.headerSize");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package com.netflix.spectator.spark;

import com.codahale.metrics.MetricRegistry;
import com.netflix.spectator.api.Spectator;
import com.netflix.spectator.gc.GcLogger;
import com.netflix.spectator.jvm.Jmx;
import com.typesafe.config.Config;
Expand Down Expand Up @@ -62,7 +61,7 @@ public SparkSink(
MetricRegistry registry,
org.apache.spark.SecurityManager manager) throws MalformedURLException {
final Config config = loadConfig();
sidecarRegistry = Spectator.registry().underlying(SidecarRegistry.class);
sidecarRegistry = new SidecarRegistry();
reporter = SpectatorReporter.forRegistry(registry)
.withNameFunction(SparkNameFunction.fromConfig(config, sidecarRegistry))
.withValueFunction(SparkValueFunction.fromConfig(config))
Expand All @@ -89,7 +88,7 @@ private ClassLoader pickClassLoader() {

private void startJvmCollection() {
try {
Jmx.registerStandardMXBeans(Spectator.registry());
Jmx.registerStandardMXBeans(sidecarRegistry);
gcLogger = new GcLogger();
gcLogger.start(null);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public Builder withGaugeCounters(Pattern pattern) {
/** Create a new instance of the reporter. */
public SpectatorReporter build() {
if (spectatorRegistry == null) {
spectatorRegistry = Spectator.registry();
spectatorRegistry = Spectator.globalRegistry();
}
return new SpectatorReporter(
registry, spectatorRegistry, nameFunction, valueFunction, gaugeCounters);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import com.netflix.spectator.api.Registry;
import iep.com.netflix.iep.http.RxHttp;
import com.netflix.spectator.api.Id;
import com.netflix.spectator.api.Spectator;
import com.netflix.spectator.gc.GcEvent;
import com.netflix.spectator.gc.GcEventListener;
import com.sun.management.GcInfo;
Expand All @@ -33,6 +32,7 @@
import rx.functions.Action0;
import rx.functions.Action1;

import javax.inject.Inject;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
Expand All @@ -55,8 +55,8 @@ class ChronosGcEventListener implements GcEventListener {

private final Logger logger = LoggerFactory.getLogger(getClass());

private final Registry registry = Spectator.registry();
private final Id requestCount = registry.createId("spectator.gc.chronosPost");
private final Registry registry;
private final Id requestCount;

private final ObjectMapper mapper = new ObjectMapper();

Expand All @@ -68,8 +68,11 @@ class ChronosGcEventListener implements GcEventListener {
private final RxHttp rxHttp;

/** Create a new instance. */
ChronosGcEventListener(RxHttp rxHttp) {
@Inject
ChronosGcEventListener(RxHttp rxHttp, Registry registry) {
this.rxHttp = rxHttp;
this.registry = registry;
requestCount = registry.createId("spectator.gc.chronosPost");
}

private String getenv(String k) {
Expand Down
Loading

0 comments on commit 1a198c6

Please sign in to comment.