package alien4cloud.webconfiguration;
import java.lang.management.ManagementFactory;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.boot.context.embedded.ServletRegistrationBean;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import com.codahale.metrics.JmxReporter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.codahale.metrics.jvm.BufferPoolMetricSet;
import com.codahale.metrics.jvm.FileDescriptorRatioGauge;
import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
import com.codahale.metrics.servlets.MetricsServlet;
import com.ryantenney.metrics.spring.config.annotation.EnableMetrics;
import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter;
@Slf4j
@Configuration
@EnableMetrics(proxyTargetClass = true)
public class MetricsConfiguration extends MetricsConfigurerAdapter implements EnvironmentAware {
private static final String ENV_METRICS = "metrics.";
private static final String PROP_JMX_ENABLED = "jmx.enabled";
private static final String PROP_METRIC_REG_JVM_MEMORY = "jvm.memory";
private static final String PROP_METRIC_REG_JVM_GARBAGE = "jvm.garbage";
private static final String PROP_METRIC_REG_JVM_THREADS = "jvm.threads";
private static final String PROP_METRIC_REG_JVM_FILES = "jvm.files";
private static final String PROP_METRIC_REG_JVM_BUFFERS = "jvm.buffers";
private static final MetricRegistry METRIC_REGISTRY = new MetricRegistry();
private static final HealthCheckRegistry HEALTH_CHECK_REGISTRY = new HealthCheckRegistry();
private RelaxedPropertyResolver propertyResolver;
private JmxReporter jmxReporter;
@Override
public void setEnvironment(Environment environment) {
this.propertyResolver = new RelaxedPropertyResolver(environment, ENV_METRICS);
}
@PostConstruct
public void init() {
log.info("Registering JVM gauges");
METRIC_REGISTRY.register(PROP_METRIC_REG_JVM_MEMORY, new MemoryUsageGaugeSet());
METRIC_REGISTRY.register(PROP_METRIC_REG_JVM_GARBAGE, new GarbageCollectorMetricSet());
METRIC_REGISTRY.register(PROP_METRIC_REG_JVM_THREADS, new ThreadStatesGaugeSet());
METRIC_REGISTRY.register(PROP_METRIC_REG_JVM_FILES, new FileDescriptorRatioGauge());
METRIC_REGISTRY.register(PROP_METRIC_REG_JVM_BUFFERS, new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
if (propertyResolver.getProperty(PROP_JMX_ENABLED, Boolean.class, false)) {
log.info("Initializing Metrics JMX reporting");
jmxReporter = JmxReporter.forRegistry(METRIC_REGISTRY).build();
jmxReporter.start();
}
}
@PreDestroy
public void destoy() {
for (String name : METRIC_REGISTRY.getNames()) {
METRIC_REGISTRY.remove(name);
}
if (jmxReporter != null) {
jmxReporter.stop();
}
}
@Override
@Bean
public MetricRegistry getMetricRegistry() {
return METRIC_REGISTRY;
}
@Override
@Bean
public HealthCheckRegistry getHealthCheckRegistry() {
return HEALTH_CHECK_REGISTRY;
}
@Bean
public MetricsServlet metricsServlet(MetricRegistry metricRegistry) {
return new MetricsServlet(metricRegistry);
}
@Bean
public FilterRegistrationBean metricsFilterRegistration(MetricRegistry metricRegistry) {
log.info("Registering Metrics filter.");
return new FilterRegistrationBean(new MetricsFilter(METRIC_REGISTRY));
}
@Bean
public ServletRegistrationBean metricsRegistration(MetricsServlet metricsServlet) {
ServletRegistrationBean registration = new ServletRegistrationBean(metricsServlet);
registration.addUrlMappings("/rest/admin/metrics/metrics/*");
return registration;
}
}