GraphiteGaugeMetric
===================
package com.tribalfusion.datagen.graphite;
import com.codahale.metrics.Gauge;
public class GraphiteGaugeMetric implements Gauge<Number> {
protected Number metric;
public GraphiteGaugeMetric() {
metric = 1;
}
public void setValue(Number status) {
if (status == null) {
throw new RuntimeException("Can't set null value");
}
this.metric = status;
}
@Override
public Number getValue() {
return metric;
}
}
================================================================================
StatusManager
=============
package com.tribalfusion.datagen.graphite;
public interface StatusManager {
public static enum ManagerType {
COMPONENT, JVM
}
public void startMonitoring();
public void stopMonitoring(String managerUniqueId);
public String getManagerUniqueId();
public boolean isMonitoringStarted();
public String getMonitorInfo();
}
================================================================================
JVMStatusManager
================
package com.tribalfusion.datagen.graphite;
import java.net.InetSocketAddress;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.graphite.Graphite;
import com.codahale.metrics.graphite.GraphiteReporter;
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.tribalfusion.datagen.properties.DatagenConsumerProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class JVMStatusManager implements StatusManager {
private static final Logger LOGGER = LoggerFactory.getLogger(JVMStatusManager.class);
private final MetricRegistry registry;
private final long interval;
private final String jvmMetricRoot;
private final String carbonHost;
private final int carbonPort;
private final String prefix;
private final String managerUniqueId;
private Graphite graphite;
private GraphiteReporter reporter;
private volatile boolean isMonitoringStarted = false;
public JVMStatusManager(int interval) {
this.registry = new MetricRegistry();
this.interval = interval;
carbonHost = DatagenConsumerProperties.carbonHost();
carbonPort = DatagenConsumerProperties.carbonPort();
prefix = MonitorConstants.CONSUMER_PREFIX; // will show in graphite like <graphite_metric_prefix>.<consumerId>
jvmMetricRoot = MonitorConstants.JVM_METRIC_ROOT; // "jvm", will show in graphite like <graphite_metric_prefix>.<consumerId>.jvm
managerUniqueId = UUID.randomUUID().toString();
registerMemoryGauze();
registerPing();
registerThreadingGauze();
registerGCGauze();
registerFDGauze();
}
@Override
public String getManagerUniqueId() {
return managerUniqueId;
}
private void registerMemoryGauze() {
MemoryUsageGaugeSet gauzeSet = new MemoryUsageGaugeSet();
for (Entry<String, Metric> current : gauzeSet.getMetrics().entrySet()) {
// will show in graphite like <graphite_metric_prefix>.<consumerId>.jvm.memory.xxxx
registry.register(jvmMetricRoot + ".memory." + current.getKey(), current.getValue());
}
}
private void registerPing() {
Gauge<Integer> ping = new Gauge<Integer>() {
@Override
public Integer getValue() {
return 1;
}
};
// will show in graphite like <graphite_metric_prefix>.<consumerId>.jvm.health.xxxx
registry.register(jvmMetricRoot + ".health", ping);
}
private void registerThreadingGauze() {
ThreadStatesGaugeSet gauzeSet = new ThreadStatesGaugeSet();
for (Entry<String, Metric> current : gauzeSet.getMetrics().entrySet()) {
// will show in graphite like <graphite_metric_prefix>.<consumerId>.jvm.threading.xxxx
registry.register(jvmMetricRoot + ".threading." + current.getKey(), current.getValue());
}
}
private void registerGCGauze() {
GarbageCollectorMetricSet gauzeSet = new GarbageCollectorMetricSet();
for (Entry<String, Metric> current : gauzeSet.getMetrics().entrySet()) {
// will show in graphite like <graphite_metric_prefix>.<consumerId>.jvm.gc.xxxx
registry.register(jvmMetricRoot + ".gc." + current.getKey(), current.getValue());
}
}
private void registerFDGauze() {
FileDescriptorRatioGauge gauzeSet = new FileDescriptorRatioGauge();
// will show in graphite like <graphite_metric_prefix>.<consumerId>.jvm.os.openFileDescriptor
registry.register(jvmMetricRoot + ".os.openFileDescriptor", gauzeSet);
}
@Override
public String getMonitorInfo() {
return "[ID: " + managerUniqueId + ", Carbon: " + carbonHost + ":" + carbonPort + ", Prefix: '" + prefix + "', Interval: " + interval + " secs]";
}
@Override
public boolean isMonitoringStarted() {
return isMonitoringStarted;
}
@Override
public synchronized void startMonitoring() {
LOGGER.info("Try to start JVM monitoring for " + getMonitorInfo());
if (isMonitoringStarted()) {
LOGGER.info("JVM monitoring already started for " + getMonitorInfo() + " .... no need to start again");
return;
}
final boolean datagenGraphiteReporterEnabled = DatagenConsumerProperties.datagenGraphiteReporterEnabled();
LOGGER.info("Graphite for JVM monitoring will be started for " + getMonitorInfo() + (datagenGraphiteReporterEnabled ? ". Starting it now." : ". Not starting it as of now."));
if (!datagenGraphiteReporterEnabled) {
return;
}
graphite = new Graphite(new InetSocketAddress(carbonHost, carbonPort));
reporter = GraphiteReporter.forRegistry(registry).prefixedWith(prefix).convertRatesTo(TimeUnit.SECONDS).convertDurationsTo(TimeUnit.MILLISECONDS).build(graphite);
reporter.start(interval, TimeUnit.SECONDS);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
stopMonitoring(managerUniqueId);
}
});
isMonitoringStarted = true;
}
@Override
public void stopMonitoring(String managerUniqueId) {
if (!this.managerUniqueId.equals(managerUniqueId)) {
throw new RuntimeException("JVM monnitoring for " + getMonitorInfo() + " can't be stopped from outside.");
}
try {
LOGGER.info("Trying to stop JVM monnitoring for " + getMonitorInfo());
reporter.close();
graphite.close();
LOGGER.info("Stopped JVM monnitoring for " + getMonitorInfo());
} catch(Exception e) {
LOGGER.error("Error while stopping JVM monnitoring for " + getMonitorInfo() + ": " + e, e);
} finally {
isMonitoringStarted = false;
}
}
}
================================================================================
ComponentStatusManager
======================
package com.tribalfusion.datagen.graphite;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricFilter;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.graphite.Graphite;
import com.codahale.metrics.graphite.GraphiteReporter;
import com.tribalfusion.datagen.properties.DatagenConsumerProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ComponentStatusManager implements StatusManager {
private static final Logger LOGGER = LoggerFactory.getLogger(ComponentStatusManager.class);
private final MetricRegistry registry;
private final long interval;
private Graphite graphite;
private GraphiteReporter reporter;
private final String carbonHost;
private final int carbonPort;
private final String prefix;
private final Map<String, GraphiteGaugeMetric> registeredGauges = new ConcurrentHashMap<>();
private final String managerUniqueId;
private volatile boolean isMonitoringStarted = false;
public ComponentStatusManager(long interval) {
registry = new MetricRegistry();
this.interval = interval;
carbonHost = DatagenConsumerProperties.carbonHost();
carbonPort = DatagenConsumerProperties.carbonPort();
prefix = MonitorConstants.CONSUMER_PREFIX; // will show in graphite like <graphite_metric_prefix>.<consumerId>
managerUniqueId = UUID.randomUUID().toString();
}
@Override
public String getManagerUniqueId() {
return managerUniqueId;
}
public GraphiteGaugeMetric registerGauge(final String name) {
GraphiteGaugeMetric registeredGauge = null;
try {
LOGGER.info("Registering gauge: '" + name + "' for COMPONENT monitor " + getMonitorInfo());
// will show in graphite like <graphite_metric_prefix>.<consumerId>.<name>
registeredGauge = registry.register(name, new GraphiteGaugeMetric());
LOGGER.info("Registered successfully gauge: '" + name + "' for COMPONENT monitor " + getMonitorInfo());
} catch(Exception e) {
registeredGauge = getGauge(name);
}
if (registeredGauge != null) {
registeredGauges.put(name, registeredGauge);
}
return registeredGauge;
}
@SuppressWarnings("rawtypes")
public GraphiteGaugeMetric getGauge(final String name) {
MetricFilter filter = new MetricFilter() {
@Override
public boolean matches(String metricName, Metric metric) {
if(name.equalsIgnoreCase(metricName)){
return true;
}
return false;
}
};
GraphiteGaugeMetric gauge = null;
Map<String, Gauge> gaugeSet = registry.getGauges(filter);
if (gaugeSet == null || gaugeSet.size() == 0) {
LOGGER.warn("No metric component found with name " + name + " for COMPONENT monitor " + getMonitorInfo());
} else {
if (gaugeSet.size() > 1) {
LOGGER.warn("More than one metric component found with name " + name + ", total Component " + gaugeSet.size() + " for COMPONENT monitor " + getMonitorInfo());
}
for (Gauge current : gaugeSet.values()) {
if (current instanceof GraphiteGaugeMetric) {
gauge = (GraphiteGaugeMetric) current;
break;
}
}
}
return gauge;
}
@Override
public String getMonitorInfo() {
return "[ID: " + managerUniqueId + ", Carbon: " + carbonHost + ":" + carbonPort + ", Prefix: '" + prefix + "', Interval: " + interval + " secs]";
}
@Override
public boolean isMonitoringStarted() {
return isMonitoringStarted;
}
@Override
public void startMonitoring() {
LOGGER.info("Try to start COMPONENT monitoring for " + getMonitorInfo());
if (isMonitoringStarted()) {
LOGGER.info("COMPONENT monitoring already started for " + getMonitorInfo() + " .... no need to start again");
return;
}
final boolean datagenGraphiteReporterEnabled = DatagenConsumerProperties.datagenGraphiteReporterEnabled();
LOGGER.info("Graphite for COMPONENT monitoring will be started for " + getMonitorInfo() + (datagenGraphiteReporterEnabled ? ". Starting it now." : ". Not starting it as of now."));
if (!datagenGraphiteReporterEnabled) {
return;
}
graphite = new Graphite(new InetSocketAddress(carbonHost, carbonPort));
reporter = GraphiteReporter.forRegistry(registry)
.prefixedWith(prefix)
.convertRatesTo(TimeUnit.SECONDS)
.convertDurationsTo(TimeUnit.MILLISECONDS)
.build(graphite);
reporter.start(interval, TimeUnit.SECONDS);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
stopMonitoring(managerUniqueId);
}
});
isMonitoringStarted = true;
}
@Override
public void stopMonitoring(String managerUniqueId) {
if (!this.managerUniqueId.equals(managerUniqueId)) {
throw new RuntimeException("COMPONENT monnitoring for " + getMonitorInfo() + " can't be stopped from outside.");
}
try {
final Collection<GraphiteGaugeMetric> allRegisteredGauge = registeredGauges.values();
LOGGER.info("Trying to stop COMPONENT monnitoring for " + getMonitorInfo() + ". Send 0 to all " + allRegisteredGauge.size() + " registered metrics");
for (GraphiteGaugeMetric registeredGauge : allRegisteredGauge) {
registeredGauge.setValue(0);
}
try {
Thread.sleep(10000);
} catch (Throwable t) {
//
}
reporter.close();
graphite.close();
LOGGER.info("Stopped COMPONENT monnitoring for " + getMonitorInfo());
} catch(Exception e) {
LOGGER.error("Error while stopping COMPONENT monnitoring for " + getMonitorInfo() + ": " + e, e);
} finally {
isMonitoringStarted = false;
}
}
}
================================================================================
Usage
=====
ComponentStatusManager statusManager = (ComponentStatusManager) StatusManagerFactory.getManager(ManagerType.COMPONENT, DatagenConsumerProperties.datagenGraphiteFlushIntervalSec());
GraphiteGaugeMetric cacheGraphiteMetric_ = statusManager.registerGauge(MonitorConstants.CACHE_METRIC_ROOT + "." + cacheType_.getCacheName_());
cacheGraphiteMetric_.setValue(ComponentStatusEnum.SUCCESS.getValue());
....
cacheGraphiteMetric_.setValue(ComponentStatusEnum.ERROR.getValue());