@Override public void activateService() { metricRegistry = new MetricRegistry(); healthCheckRegistry = new HealthCheckRegistry(); CodahaleMetricsDeclaration declaration = descriptor.metaInfo( CodahaleMetricsDeclaration.class ); prefix = declaration.prefix() != null ? declaration.prefix() : app.name(); fqcn = declaration.fqcn(); if( declaration.jmx() ) { JmxReporter jmxReporter = JmxReporter.forRegistry( metricRegistry ).build(); jmxReporter.start(); reporters.add( jmxReporter ); } for( Function<MetricRegistry, Reporter> reporterFactory : declaration.reportersFactories()) { reporters.add( reporterFactory.apply( metricRegistry ) ); } }
@Test public void register() throws Exception { new MockUnit(MetricRegistry.class, Metric.class, Reporter.class, ConsoleReporter.class) .expect(unit -> { MetricRegistry registry = unit.get(MetricRegistry.class); expect(registry.register("m", unit.get(Metric.class))) .andReturn(unit.get(Metric.class)); }) .expect(unit -> { unit.get(ConsoleReporter.class).close(); }) .run(unit -> { Map<String, Metric> metrics = ImmutableMap.of("m", unit.get(Metric.class)); Set<Reporter> reporters = ImmutableSet.of(unit.get(Reporter.class), unit.get(ConsoleReporter.class)); MetricRegistryInitializer mri = new MetricRegistryInitializer( unit.get(MetricRegistry.class), metrics, reporters); mri.close(); }); }
@Test public void closeWithError() throws Exception { new MockUnit(MetricRegistry.class, Metric.class, Reporter.class, ConsoleReporter.class) .expect(unit -> { MetricRegistry registry = unit.get(MetricRegistry.class); expect(registry.register("m", unit.get(Metric.class))) .andReturn(unit.get(Metric.class)); }) .expect(unit -> { unit.get(ConsoleReporter.class).close(); expectLastCall().andThrow(new IllegalStateException("intentional err")); }) .run(unit -> { Map<String, Metric> metrics = ImmutableMap.of("m", unit.get(Metric.class)); Set<Reporter> reporters = ImmutableSet.of(unit.get(Reporter.class), unit.get(ConsoleReporter.class)); MetricRegistryInitializer mri = new MetricRegistryInitializer( unit.get(MetricRegistry.class), metrics, reporters); mri.close(); }); }
@Override public synchronized Reporter getReporter(MetricRegistry registry) { if (null == reporter) { Graphite graphite = new Graphite(new InetSocketAddress(graphiteURL, graphitePort)); reporter = GraphiteReporter.forRegistry(registry) .prefixedWith(prefix) .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS) .filter(MetricFilter.ALL) .build(graphite); } return reporter; }
@Override public synchronized Reporter getReporter(MetricRegistry registry) { if (null == reporter) { reporter = Slf4jReporter.forRegistry(registry) .outputTo(LoggerFactory.getLogger(prefix)) .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS) .build(); } return reporter; }
@Override public synchronized Reporter getReporter(MetricRegistry registry) { if (null == reporter) { reporter = JmxReporter.forRegistry(registry).build(); } return reporter; }
@Override public synchronized Reporter getReporter(MetricRegistry registry) { if (null == reporter) { reporter = ConsoleReporter.forRegistry(registry) .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS) .build(); } return reporter; }
@Test public void test() { MetricRegistry registry = new MetricRegistry(); Reporter r = new DefaultConsoleReporterFactory().getReporter(registry); assertNotNull(r); r = new DefaultJMXReporterFactory().getReporter(registry); assertNotNull(r); r = new DefaultSLF4jReporterFactory().getReporter(registry); assertNotNull(r); r = new DefaultGraphiteReporterFactory("test", "fakeurl.com", 4242).getReporter(registry); assertNotNull(r); r = new RiposteGraphiteReporterFactory("test", "fakeurl.com", 4242).getReporter(registry); }
@Inject public MetricRegistryInitializer(final MetricRegistry registry, final Map<String, Metric> metrics, final Set<Reporter> reporters) { metrics.forEach(registry::register); reporters.forEach(reporter -> { if (reporter instanceof Closeable) { this.reporters.add((Closeable) reporter); } }); }
@SuppressWarnings("unchecked") @Test public void basic() throws Exception { new MockUnit(Env.class, Config.class, Binder.class, Jooby.class, MetricRegistryInitializer.class) .expect(newMetricRegistry) .expect(newHealthCheckRegistry) .expect(mapBinderStatic) .expect(mapbinder(Metric.class, (unit, binder) -> { })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { })) .expect(multibinderStatic) .expect(routes) .expect(setbinder(Reporter.class, (unit, binder) -> { })) .expect(bindMetricRegistry) .expect(bindMetricRegistryInitializer) .expect(bindHealthCheckRegistry) .expect(bindHealthCheckRegistryInitializer) .expect(onStop) .expect(unit -> { MetricRegistryInitializer closer = unit.get(MetricRegistryInitializer.class); closer.close(); Jooby app = unit.get(Jooby.class); expect(app.require(MetricRegistryInitializer.class)).andReturn(closer); }) .run(unit -> { new Metrics() .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }, unit -> { unit.captured(Throwing.Consumer.class).get(0).accept(unit.get(Jooby.class)); }); }
@Test public void request() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .expect(newMetricRegistry) .expect(newHealthCheckRegistry) .expect(mapBinderStatic) .expect(mapbinder(Metric.class, (unit, binder) -> { })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { })) .expect(multibinderStatic) .expect(unit -> { Router routes = unit.mock(Router.class); Env env = unit.get(Env.class); expect(env.router()).andReturn(routes); MetricHandler handler = unit.constructor(MetricHandler.class).build(); route(unit, routes, "/sys/metrics", handler); route(unit, routes, "/sys/metrics/:type", handler); route(unit, routes, "/sys/healthcheck", unit.constructor(HealthCheckHandler.class).build()); route(unit, routes, "*", unit.constructor(InstrumentedHandler.class).build()); }) .expect(setbinder(Reporter.class, (unit, binder) -> { })) .expect(bindMetricRegistry) .expect(bindMetricRegistryInitializer) .expect(bindHealthCheckRegistry) .expect(bindHealthCheckRegistryInitializer) .expect(onStop) .run(unit -> { Metrics metrics = new Metrics().request(); metrics.configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); }
@SuppressWarnings("unchecked") @Test public void metricInstance() throws Exception { new MockUnit(Env.class, Config.class, Binder.class, Metric.class) .expect(newMetricRegistry) .expect(newHealthCheckRegistry) .expect(mapBinderStatic) .expect(mapbinder(Metric.class, (unit, binder) -> { })) .expect(mapbinder(Metric.class, (unit, binder) -> { LinkedBindingBuilder<Metric> mLBB = unit.mock(LinkedBindingBuilder.class); mLBB.toInstance(unit.get(Metric.class)); expect(binder.addBinding("m")).andReturn(mLBB); })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { })) .expect(multibinderStatic) .expect(routes) .expect(setbinder(Reporter.class, (unit, binder) -> { })) .expect(bindMetricRegistry) .expect(bindMetricRegistryInitializer) .expect(bindHealthCheckRegistry) .expect(bindHealthCheckRegistryInitializer) .expect(onStop) .run(unit -> { new Metrics() .metric("m", unit.get(Metric.class)) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); }
@SuppressWarnings("unchecked") @Test public void metricRef() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .expect(newMetricRegistry) .expect(newHealthCheckRegistry) .expect(mapBinderStatic) .expect(mapbinder(Metric.class, (unit, binder) -> { })) .expect(mapbinder(Metric.class, (unit, binder) -> { LinkedBindingBuilder<Metric> mLBB = unit.mock(LinkedBindingBuilder.class); expect(mLBB.to(Meter.class)).andReturn(null); expect(binder.addBinding("m")).andReturn(mLBB); })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { })) .expect(multibinderStatic) .expect(routes) .expect(setbinder(Reporter.class, (unit, binder) -> { })) .expect(bindMetricRegistry) .expect(bindMetricRegistryInitializer) .expect(bindHealthCheckRegistry) .expect(bindHealthCheckRegistryInitializer) .expect(onStop) .run(unit -> { new Metrics() .metric("m", Meter.class) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); }
@SuppressWarnings("unchecked") @Test public void healthCheck() throws Exception { new MockUnit(Env.class, Config.class, Binder.class, HealthCheck.class) .expect(newMetricRegistry) .expect(newHealthCheckRegistry) .expect(mapBinderStatic) .expect(mapbinder(Metric.class, (unit, binder) -> { })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { LinkedBindingBuilder<HealthCheck> mLBB = unit.mock(LinkedBindingBuilder.class); mLBB.toInstance(unit.get(HealthCheck.class)); expect(binder.addBinding("h")).andReturn(mLBB); })) .expect(multibinderStatic) .expect(routes) .expect(setbinder(Reporter.class, (unit, binder) -> { })) .expect(bindMetricRegistry) .expect(bindMetricRegistryInitializer) .expect(bindHealthCheckRegistry) .expect(bindHealthCheckRegistryInitializer) .expect(onStop) .run(unit -> { new Metrics() .healthCheck("h", unit.get(HealthCheck.class)) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); }
@SuppressWarnings("unchecked") @Test public void healthRef() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .expect(newMetricRegistry) .expect(newHealthCheckRegistry) .expect(mapBinderStatic) .expect(mapbinder(Metric.class, (unit, binder) -> { })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { LinkedBindingBuilder<HealthCheck> mLBB = unit.mock(LinkedBindingBuilder.class); expect(mLBB.to(HealthCheck.class)).andReturn(null); expect(binder.addBinding("h")).andReturn(mLBB); })) .expect(multibinderStatic) .expect(routes) .expect(setbinder(Reporter.class, (unit, binder) -> { })) .expect(bindMetricRegistry) .expect(bindMetricRegistryInitializer) .expect(bindHealthCheckRegistry) .expect(bindHealthCheckRegistryInitializer) .expect(onStop) .run(unit -> { new Metrics() .healthCheck("h", HealthCheck.class) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); }
@SuppressWarnings("unchecked") @Test public void reporter() throws Exception { new MockUnit(Env.class, Config.class, Binder.class) .expect(newMetricRegistry) .expect(newHealthCheckRegistry) .expect(mapBinderStatic) .expect(mapbinder(Metric.class, (unit, binder) -> { })) .expect(mapbinder(HealthCheck.class, (unit, binder) -> { })) .expect(multibinderStatic) .expect(routes) .expect(setbinder(Reporter.class, (unit, binder) -> { LinkedBindingBuilder<Reporter> rLBB = unit.mock(LinkedBindingBuilder.class); rLBB.toInstance(isA(ConsoleReporter.class)); expect(binder.addBinding()).andReturn(rLBB); })) .expect(bindMetricRegistry) .expect(bindMetricRegistryInitializer) .expect(bindHealthCheckRegistry) .expect(bindHealthCheckRegistryInitializer) .expect(onStop) .run(unit -> { new Metrics() .reporter(r -> { return ConsoleReporter.forRegistry(r).build(); }) .configure(unit.get(Env.class), unit.get(Config.class), unit.get(Binder.class)); }); }
@Override public Reporter getReporter(MetricRegistry registry) { return this; }
public List<Function<MetricRegistry, Reporter>> reportersFactories() { return reportersFactories; }
public CodahaleMetricsAssembler withReporter( Function<MetricRegistry, Reporter> factory ) { declaration.reportersFactories.add( factory ); return this; }
@Override public void configure(final Env env, final Config conf, final Binder binder) { // empty metric & checks MapBinder.newMapBinder(binder, String.class, Metric.class); MapBinder.newMapBinder(binder, String.class, HealthCheck.class); Router routes = env.router(); MetricHandler mhandler = new MetricHandler(); routes.use("GET", this.pattern + "/metrics", mhandler); routes.use("GET", this.pattern + "/metrics/:type", mhandler); routes.use("GET", this.pattern + "/healthcheck", new HealthCheckHandler()); Multibinder<Reporter> reporters = Multibinder.newSetBinder(binder, Reporter.class); binder.bind(MetricRegistry.class).toInstance(metricRegistry); this.reporters.forEach(it -> reporters.addBinding().toInstance(it.apply(metricRegistry, conf))); binder.bind(MetricRegistryInitializer.class).asEagerSingleton(); env.onStop(app -> app.require(MetricRegistryInitializer.class).close()); binder.bind(HealthCheckRegistry.class).toInstance(healthCheckRegistry); binder.bind(HealthCheckRegistryInitializer.class).asEagerSingleton(); bindings.forEach(it -> it.bind(binder, routes, conf)); this.routes.forEach(it -> it.accept(routes)); }
/** * Get the singleton instance of the Reporter wrapped by this ReporterFactory * * @param registry * The MetricRegistry that the Reporter will be reporting on */ Reporter getReporter(MetricRegistry registry);
/** * Builds a reporter with this definition * @param metricRegistry the metrics registry * @param creatingExchange the camel exchange * @param metricGroup the metric group * @return the scheduled reporter */ Reporter buildReporter(final MetricRegistry metricRegistry, final Exchange creatingExchange, final MetricGroup metricGroup);
/** * Append a {@link Reporter} to the {@link MetricRegistry}. * * @param callback Reporter callback. * @return This metrics module. */ public Metrics reporter(final BiFunction<MetricRegistry, Config, Reporter> callback) { this.reporters.add(requireNonNull(callback, "Callback is required.")); return this; }
/** * Append a {@link Reporter} to the {@link MetricRegistry}. * * @param callback Reporter callback. * @return This metrics module. */ public Metrics reporter(final Function<MetricRegistry, Reporter> callback) { return reporter((registry, conf) -> callback.apply(registry)); }