You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
158 lines
4.8 KiB
158 lines
4.8 KiB
package org.airsonic.player.monitor;
|
|
|
|
import com.codahale.metrics.JmxReporter;
|
|
import com.codahale.metrics.MetricRegistry;
|
|
import org.airsonic.player.service.ApacheCommonsConfigurationService;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/**
|
|
* Created by remi on 17/01/17.
|
|
*/
|
|
@Service
|
|
public class MetricsManager {
|
|
|
|
@Autowired
|
|
private ApacheCommonsConfigurationService configurationService;
|
|
|
|
// Main metrics registry
|
|
private static final MetricRegistry metrics = new MetricRegistry();
|
|
|
|
private static volatile Boolean metricsActivatedByConfiguration = null;
|
|
private static Object _lock = new Object();
|
|
|
|
// Potential metrics reporters
|
|
private static JmxReporter reporter;
|
|
|
|
private void configureMetricsActivation() {
|
|
if (configurationService.containsKey("Metrics")) {
|
|
metricsActivatedByConfiguration = Boolean.TRUE;
|
|
|
|
// Start a Metrics JMX reporter
|
|
reporter = JmxReporter.forRegistry(metrics)
|
|
.convertRatesTo(TimeUnit.SECONDS)
|
|
.convertDurationsTo(TimeUnit.MILLISECONDS)
|
|
.build();
|
|
reporter.start();
|
|
} else {
|
|
metricsActivatedByConfiguration = Boolean.FALSE;
|
|
}
|
|
}
|
|
|
|
private boolean metricsActivatedByConfiguration() {
|
|
if (metricsActivatedByConfiguration == null) {
|
|
synchronized (_lock) {
|
|
if (metricsActivatedByConfiguration == null) {
|
|
configureMetricsActivation();
|
|
}
|
|
}
|
|
}
|
|
return metricsActivatedByConfiguration;
|
|
}
|
|
|
|
/**
|
|
* Creates a {@link Timer} whose name is based on a class name and a
|
|
* qualified name.
|
|
*/
|
|
public Timer timer(Class clazz, String name) {
|
|
if (metricsActivatedByConfiguration()) {
|
|
return new TimerBuilder().timer(clazz, name);
|
|
} else {
|
|
return nullTimerSingleton;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a {@link Timer} whose name is based on an object's class name and a
|
|
* qualified name.
|
|
*/
|
|
public Timer timer(Object ref, String name) {
|
|
return timer(ref.getClass(),name);
|
|
}
|
|
|
|
/**
|
|
* Initiate a {@link TimerBuilder} using a condition.
|
|
* If the condition is false, a void {@link Timer} will finally be built thus
|
|
* no timer will be registered in the Metrics registry.
|
|
*/
|
|
public TimerBuilder condition(boolean ifTrue) {
|
|
if (metricsActivatedByConfiguration()) {
|
|
if (!ifTrue) {
|
|
return conditionFalseTimerBuilderSingleton;
|
|
}
|
|
return new TimerBuilder();
|
|
} else {
|
|
return nullTimerBuilderSingleton;
|
|
}
|
|
}
|
|
|
|
public void setConfigurationService(ApacheCommonsConfigurationService configurationService) {
|
|
this.configurationService = configurationService;
|
|
}
|
|
|
|
/**
|
|
* A class that builds a {@link Timer}
|
|
*/
|
|
public static class TimerBuilder {
|
|
|
|
public Timer timer(Class clazz, String name) {
|
|
com.codahale.metrics.Timer t = metrics.timer(MetricRegistry.name(clazz,name));
|
|
com.codahale.metrics.Timer.Context tContext = t.time();
|
|
return new Timer(tContext);
|
|
}
|
|
|
|
public Timer timer(Object ref, String name) {
|
|
return timer(ref.getClass(),name);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* A class that holds a Metrics timer context implementing {@link AutoCloseable}
|
|
* thus it can be used in a try-with-resources statement.
|
|
*/
|
|
public static class Timer implements AutoCloseable {
|
|
|
|
private com.codahale.metrics.Timer.Context timerContext;
|
|
|
|
protected Timer(com.codahale.metrics.Timer.Context timerContext) {
|
|
this.timerContext = timerContext;
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
timerContext.stop();
|
|
}
|
|
|
|
}
|
|
|
|
|
|
// -----------------------------------------------------------------
|
|
// Convenient singletons to avoid creating useless objects instances
|
|
// -----------------------------------------------------------------
|
|
private static final NullTimer nullTimerSingleton = new NullTimer(null);
|
|
private static final NullTimerBuilder conditionFalseTimerBuilderSingleton = new NullTimerBuilder();
|
|
private static final NullTimerBuilder nullTimerBuilderSingleton = new NullTimerBuilder();
|
|
|
|
private static class NullTimer extends Timer {
|
|
|
|
protected NullTimer(com.codahale.metrics.Timer.Context timerContext) {
|
|
super(timerContext);
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
// Does nothing
|
|
}
|
|
}
|
|
|
|
private static class NullTimerBuilder extends TimerBuilder {
|
|
@Override
|
|
public Timer timer(Class clazz, String name) {
|
|
return nullTimerSingleton;
|
|
}
|
|
}
|
|
|
|
}
|
|
|