package restx.monitor; import com.codahale.metrics.DefaultObjectNameFactory; import com.codahale.metrics.JmxReporter; import com.codahale.metrics.MetricRegistry; import com.codahale.metrics.ObjectNameFactory; import com.codahale.metrics.graphite.Graphite; import com.codahale.metrics.graphite.GraphiteReporter; import com.codahale.metrics.health.HealthCheckRegistry; import com.codahale.metrics.health.jvm.ThreadDeadlockHealthCheck; import com.codahale.metrics.jvm.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import restx.AppSettings; import restx.RestxContext; import restx.factory.AutoStartable; import restx.factory.Component; import restx.metrics.codahale.CodahaleMetricRegistry; import restx.metrics.codahale.health.CodahaleHealthCheckRegistry; import javax.management.ObjectName; import java.lang.management.ManagementFactory; import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; /** * Date: 17/11/13 * Time: 00:25 */ @Component public class MetricsConfiguration implements AutoStartable { private static final Logger logger = LoggerFactory.getLogger(MetricsConfiguration.class); private final MetricRegistry metrics; private final HealthCheckRegistry healthChecks; private final GraphiteSettings graphiteSettings; private final AppSettings appSettings; public MetricsConfiguration(restx.common.metrics.api.MetricRegistry metricRegistry, restx.common.metrics.api.health.HealthCheckRegistry healthCheckRegistry, GraphiteSettings graphiteSettings, AppSettings appSettings) { if (!(metricRegistry instanceof CodahaleMetricRegistry)){ throw new IllegalStateException("restx-monitor-admin expects that module restx-monitor-codahale is loaded"); } CodahaleMetricRegistry codahaleMetricRegistry = (CodahaleMetricRegistry) metricRegistry; CodahaleHealthCheckRegistry codahaleHealthCheckRegistry = (CodahaleHealthCheckRegistry) healthCheckRegistry; this.metrics = codahaleMetricRegistry.getCodahaleMetricRegistry(); this.healthChecks = codahaleHealthCheckRegistry.getCodahaleHealthCheckRegistry(); this.graphiteSettings = graphiteSettings; this.appSettings = appSettings; } @Override public void start() { if (RestxContext.Modes.PROD.equals(appSettings.mode()) || RestxContext.Modes.DEV.equals(appSettings.mode())) { logger.info("registering Metrics JVM metrics"); metrics.register("jvm.memory", new MemoryUsageGaugeSet()); metrics.register("jvm.garbage", new GarbageCollectorMetricSet()); metrics.register("jvm.threads", new ThreadStatesGaugeSet()); metrics.register("jvm.files", new FileDescriptorRatioGauge()); metrics.register("jvm.buffers", new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer())); healthChecks.register("threadLocks", new ThreadDeadlockHealthCheck()); } if (RestxContext.Modes.PROD.equals(appSettings.mode())) { setupReporters(); } } protected void setupReporters() { setupJmxReporter(); setupGraphiteReporter(); } protected void setupJmxReporter() { logger.info("Initializing Metrics JMX Reporter"); final JmxReporter jmxReporter = JmxReporter.forRegistry(metrics) .createsObjectNamesWith(new DefaultObjectNameFactory() { Pattern wildcards = Pattern.compile("[\\*\\?]"); @Override public ObjectName createName(String type, String domain, String name) { if (wildcards.matcher(name).find()) { name = ObjectName.quote(name); } return super.createName(type, domain, name); } }).build(); jmxReporter.start(); } protected void setupGraphiteReporter() { if (graphiteSettings.getGraphiteHost().isPresent()) { InetSocketAddress address = new InetSocketAddress( graphiteSettings.getGraphiteHost().get(), graphiteSettings.getGraphitePort().or(2003)); logger.info("Initializing Metrics Graphite reporting to {}", address); GraphiteReporter.Builder builder = GraphiteReporter.forRegistry(metrics); if (graphiteSettings.getPrefix().isPresent()) { String prefix = graphiteSettings.getPrefix().get(); builder.prefixedWith(prefix); logger.info("Metrics Graphite prefix is set to '{}'", prefix); } GraphiteReporter graphiteReporter = builder .convertRatesTo(TimeUnit.SECONDS) .convertDurationsTo(TimeUnit.MILLISECONDS) .build(new Graphite(address)); graphiteReporter.start(graphiteSettings.getFrequency().get(), TimeUnit.valueOf(graphiteSettings.getFrequencyUnit().get())); } } }