package org.infinispan.stats.impl;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.infinispan.configuration.global.GlobalConfiguration;
import org.infinispan.factories.annotations.Inject;
import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
import org.infinispan.jmx.annotations.DisplayType;
import org.infinispan.jmx.annotations.MBean;
import org.infinispan.jmx.annotations.ManagedAttribute;
import org.infinispan.jmx.annotations.MeasurementType;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.stats.ClusterContainerStats;
import org.infinispan.util.concurrent.CompletableFutures;
import org.infinispan.util.logging.Log;
import org.infinispan.util.logging.LogFactory;
/**
* @author Ryan Emerson
* @since 9.0
*/
@Scope(Scopes.GLOBAL)
@MBean(objectName = "ClusterContainerStats", description = "General container statistics aggregated across the cluster.")
public class ClusterContainerStatsImpl extends AbstractClusterStats implements ClusterContainerStats {
private static final Log log = LogFactory.getLog(ClusterContainerStatsImpl.class);
// Memory
private static final String MEMORY_AVAILABLE = "memoryAvailable";
private static final String MEMORY_MAX = "memoryMax";
private static final String MEMORY_TOTAL = "memoryTotal";
private static final String MEMORY_USED = "memoryUsed";
private static final String[] LONG_ATTRIBUTES = new String[]{MEMORY_AVAILABLE, MEMORY_MAX, MEMORY_TOTAL, MEMORY_USED};
private EmbeddedCacheManager cacheManager;
public ClusterContainerStatsImpl() {
super(log);
}
@Inject
public void init(EmbeddedCacheManager cacheManager,
GlobalConfiguration configuration) {
this.cacheManager = cacheManager;
this.statisticsEnabled = configuration.globalJmxStatistics().enabled();
}
@Override
void updateStats() throws Exception {
List<Map<String, Number>> memoryMap = getClusterStatMaps();
for (String att : LONG_ATTRIBUTES)
putLongAttributes(memoryMap, att);
}
private List<Map<String, Number>> getClusterStatMaps() throws Exception {
final List<Map<String, Number>> successfulResponseMaps = new ArrayList<>();
CompletableFutures.await(cacheManager.executor().submit(() -> {
Map<String, Number> map = new HashMap<>();
long available = Runtime.getRuntime().freeMemory();
long total = Runtime.getRuntime().totalMemory();
map.put(MEMORY_AVAILABLE, available);
map.put(MEMORY_MAX, Runtime.getRuntime().maxMemory());
map.put(MEMORY_TOTAL, total);
map.put(MEMORY_USED, total - available);
successfulResponseMaps.add(map);
}));
return successfulResponseMaps;
}
@ManagedAttribute(description = "The maximum amount of free memory in bytes across the cluster JVMs",
displayName = "Cluster wide available memory.",
measurementType = MeasurementType.DYNAMIC,
displayType = DisplayType.SUMMARY)
@Override
public long getMemoryAvailable() {
return getStatAsLong(MEMORY_AVAILABLE);
}
@ManagedAttribute(description = "The maximum amount of memory that JVMs across the cluster will attempt to utilise in bytes",
displayName = "Cluster wide max memory of JVMs",
measurementType = MeasurementType.DYNAMIC,
displayType = DisplayType.SUMMARY)
@Override
public long getMemoryMax() {
return getStatAsLong(MEMORY_MAX);
}
@ManagedAttribute(description = "The total amount of memory in the JVMs across the cluster in bytes",
displayName = "Cluster wide total memory",
measurementType = MeasurementType.DYNAMIC,
displayType = DisplayType.SUMMARY)
@Override
public long getMemoryTotal() {
return getStatAsLong(MEMORY_TOTAL);
}
@ManagedAttribute(description = "The amount of memory used by JVMs across the cluster in bytes",
displayName = "Cluster wide memory utilisation",
measurementType = MeasurementType.DYNAMIC,
displayType = DisplayType.SUMMARY)
@Override
public long getMemoryUsed() {
return getStatAsLong(MEMORY_USED);
}
}