diff --git a/README.md b/README.md index c3a1716fc..be40e2b9b 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ To instrument your code you need to depend on the api library. This provides the for you to code against and build test cases. The only dependency is slf4j. ``` -com.netflix.spectator:spectator-api:0.25.0 +com.netflix.spectator:spectator-api:0.29.0 ``` If running at Netflix with the standard platform, see the @@ -40,65 +40,66 @@ Suppose we have a server and we want to keep track of: Here is some sample code that does that: ```java -// The Spectator class provides a static lookup for the default registry -Server s = new Server(Spectator.registry()); +// In the application initialization setup a registry +Registry registry = new DefaultRegistry(); +Server s = new Server(registry); public class Server { - private final ExtendedRegistry registry; + private final Registry registry; private final Id requestCountId; private final Timer requestLatency; private final DistributionSummary responseSizes; - // We can pass in the registry to make unit testing easier. Outside of tests it should typically - // be bound to Spectator.registry() to make sure data goes to the right place. - public Server(ExtendedRegistry registry) { + @Inject + public Server(Registry registry) { this.registry = registry; - // Create a base id for the request count. The id will get refined with additional dimensions - // when we receive a request. + // Create a base id for the request count. The id will get refined with + // additional dimensions when we receive a request. requestCountId = registry.createId("server.requestCount"); - // Create a timer for tracking the latency. The reference can be held onto to avoid - // additional lookup cost in critical paths. + // Create a timer for tracking the latency. The reference can be held onto + // to avoid additional lookup cost in critical paths. requestLatency = registry.timer("server.requestLatency"); // Create a distribution summary meter for tracking the response sizes. responseSizes = registry.distributionSummary("server.responseSizes"); - // Gauge type that can be sampled. In this case it will invoke the specified method via - // reflection to get the value. The registry will keep a weak reference to the object passed - // in so that registration will not prevent garbage collection of the server object. + // Gauge type that can be sampled. In this case it will invoke the + // specified method via reflection to get the value. The registry will + // keep a weak reference to the object passed in so that registration will + // not prevent garbage collection of the server object. registry.methodValue("server.numConnections", this, "getNumConnections"); } public Response handle(Request req) { final long s = System.nanoTime(); - try { - Response res = doSomething(req); - - // Update the counter id with dimensions based on the request. The counter will then - // be looked up in the registry which should be fairly cheap, such as lookup of id object - // in a ConcurrentHashMap. However, it is more expensive than having a local variable set - // to the counter. - final Id cntId = requestCountId - .withTag("country", req.country()) - .withTag("status", res.status()); - registry.counter(cntId).increment(); - - responseSizes.record(res.body().size()); - - return res; - } catch (Exception e) { - final Id cntId = requestCountId - .withTag("country", req.country()) - .withTag("status", "exception") - .withTag("error", e.getClass().getSimpleName()); - registry.counter(cntId).increment(); - throw e; - } finally { - // Update the latency timer. This should typically be done in a finally block. - requestLatency.record(System.nanoTime() - s, TimeUnit.NANOSECONDS); - } + requestLatency.record(() -> { + try { + Response res = doSomething(req); + + // Update the counter id with dimensions based on the request. The + // counter will then be looked up in the registry which should be + // fairly cheap, such as lookup of id object in a ConcurrentHashMap. + // However, it is more expensive than having a local variable set + // to the counter. + final Id cntId = requestCountId + .withTag("country", req.country()) + .withTag("status", res.status()); + registry.counter(cntId).increment(); + + responseSizes.record(res.body().size()); + + return res; + } catch (Exception e) { + final Id cntId = requestCountId + .withTag("country", req.country()) + .withTag("status", "exception") + .withTag("error", e.getClass().getSimpleName()); + registry.counter(cntId).increment(); + throw e; + } + }); } public int getNumConnections() {