package org.apereo.cas.monitor;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.monitor.LocalMapStats;
import org.apereo.cas.configuration.model.support.hazelcast.HazelcastProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* This is {@link HazelcastMonitor}.
*
* @author Misagh Moayyed
* @since 5.0.0
*/
public class HazelcastMonitor extends AbstractCacheMonitor {
private static final Logger LOGGER = LoggerFactory.getLogger(HazelcastMonitor.class);
public HazelcastMonitor() {
super(HazelcastMonitor.class.getSimpleName());
}
@Override
protected CacheStatistics[] getStatistics() {
final List<CacheStatistics> statsList = new ArrayList<>();
final HazelcastProperties hz = casProperties.getTicket().getRegistry().getHazelcast();
LOGGER.debug("Locating hazelcast instance [{}]...", hz.getCluster().getInstanceName());
final HazelcastInstance instance = Hazelcast.getHazelcastInstanceByName(hz.getCluster().getInstanceName());
instance.getConfig().getMapConfigs().keySet().forEach(key -> {
final IMap map = instance.getMap(key);
LOGGER.debug("Starting to collect hazelcast statistics for map [{}] identified by key [{}]...", map, key);
statsList.add(new HazelcastStatistics(map, hz.getCluster().getMembers().size()));
});
return statsList.toArray(new CacheStatistics[statsList.size()]);
}
/**
* The type Hazelcast statistics.
*/
public static class HazelcastStatistics implements CacheStatistics {
private static final int PERCENTAGE_VALUE = 100;
private IMap map;
private int clusterSize;
protected HazelcastStatistics(final IMap map, final int clusterSize) {
this.map = map;
this.clusterSize = clusterSize;
}
@Override
public long getSize() {
return this.map.size();
}
@Override
public long getCapacity() {
return this.map.getLocalMapStats() != null ? this.map.getLocalMapStats().total() : 0;
}
@Override
public long getEvictions() {
if (this.map.getLocalMapStats() != null && this.map.getLocalMapStats().getNearCacheStats() != null) {
return this.map.getLocalMapStats().getNearCacheStats().getMisses();
}
return 0;
}
@Override
public String getName() {
return this.map.getName();
}
@Override
public int getPercentFree() {
final long capacity = getCapacity();
if (capacity == 0) {
return 0;
}
return (int) ((capacity - getSize()) * PERCENTAGE_VALUE / capacity);
}
@Override
public void toString(final StringBuilder builder) {
final LocalMapStats localMapStats = map.getLocalMapStats();
builder.append("Creation time: ")
.append(localMapStats.getCreationTime())
.append(", ")
.append("Cluster size: ")
.append(clusterSize)
.append(", ")
.append("Owned entry count: ")
.append(localMapStats.getOwnedEntryCount())
.append(", ")
.append("Backup entry count: ")
.append(localMapStats.getBackupEntryCount())
.append(", ")
.append("Backup count: ")
.append(localMapStats.getBackupCount())
.append(", ")
.append("Hits count: ")
.append(localMapStats.getHits())
.append(", ")
.append("Last update time: ")
.append(localMapStats.getLastUpdateTime())
.append(", ")
.append("Last access time: ")
.append(localMapStats.getLastAccessTime())
.append(", ")
.append("Locked entry count: ")
.append(localMapStats.getLockedEntryCount())
.append(", ")
.append("Dirty entry count: ")
.append(localMapStats.getDirtyEntryCount())
.append(", ")
.append("Total get latency: ")
.append(localMapStats.getMaxGetLatency())
.append(", ")
.append("Total put latency: ")
.append(localMapStats.getTotalPutLatency())
.append(", ")
.append("Total remove latency: ")
.append(localMapStats.getTotalRemoveLatency())
.append(", ")
.append("Heap cost: ")
.append(localMapStats.getHeapCost());
if (localMapStats.getNearCacheStats() != null) {
builder.append(", Misses: ")
.append(localMapStats.getNearCacheStats().getMisses());
}
}
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
this.toString(builder);
return builder.toString();
}
}
}