Alachisoft.NCache.Common.Monitoring.MetricsPublisher Maven / Gradle / Ivy
package Alachisoft.NCache.Common.Monitoring;
import Alachisoft.NCache.Common.AppUtil;
import Alachisoft.NCache.Common.IDisposable;
import Alachisoft.NCache.Common.Logger.*;
import Alachisoft.NCache.Common.Monitoring.*;
//import Alachisoft.NCache.Common.Monitoring.MetricsServer.*;
import Alachisoft.NCache.Common.ServiceConfiguration;
import Alachisoft.NCache.Common.Threading.ThreadPool;
import Alachisoft.NCache.Common.Util.*;
import com.alachisoft.ncache.common.caching.statistics.monitoring.CounterIDMap;
import com.alachisoft.ncache.common.caching.statistics.monitoring.PublisherContextMetaPublisher;
import com.alachisoft.ncache.common.monitoring.*;
import com.alachisoft.ncache.runtime.exceptions.ConfigurationException;
import com.alachisoft.ncache.runtime.util.NCDateTime;
import tangible.RefObject;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class MetricsPublisher implements IDisposable
{
private long startTime = 0;
private long _waitIntervalTime =1; //Interval time
private final long _resetWaitTime=1; //constant value
private long _increment=1;
private long _incrementPercentage=5; //Incremantal percentage
private Object _mutex = new Object();
private Thread _dataCollector, _dataPublisher;
private boolean stopPublishing = false;
private boolean _metaDataRequired = true;
private boolean _publishMetadata = true;
// bool _inPublishMetadataProcess = true;
private CounterIDMap _counterIdMap;
private HashMap> _monitorableEntities = new HashMap>();
private MonitorableEntitiesDataStore _entitiesDataStore = new MonitorableEntitiesDataStore(2);
private ArrayList _intervalCounterCollection = new ArrayList();
private MetricsTransporterFactory factoryInstance;
private MetricsTransporter _transporter;
private PublisherContextMetaPublisher _contextMetaPublisher;
private HashMap _exceptionLogger = new HashMap();
private Map _systemMetricsDictionary = new HashMap();
private String privateSessionId;
public final long getIntervalTime(){return _waitIntervalTime;}
public final void setIntervalTime(long ticks){ _waitIntervalTime =ticks;}
public final long getIncrementPercentage(){return _incrementPercentage;}
public final void setIncrementPercentage(long value){ _incrementPercentage=value;}
private String serviceBindedIp = null;
public final String getSessionId()
{
return privateSessionId;
}
public final void setSessionId(String value)
{
privateSessionId = value;
}
private String privateCacheConfigID;
public final String getCacheConfigID()
{
return privateCacheConfigID;
}
public final void setCacheConfigID(String value)
{
privateCacheConfigID = value;
}
private static MetricsPublisher privateInstance;
public static MetricsPublisher getInstance()
{
return privateInstance;
}
private static void setInstance(MetricsPublisher value)
{
privateInstance = value;
}
private CounterMetadataCollection privateCounterMetadataCollection;
public final CounterMetadataCollection getCounterMetadataCollection()
{
return privateCounterMetadataCollection;
}
public final void setCounterMetadataCollection(CounterMetadataCollection value)
{
privateCounterMetadataCollection = value;
}
private ILogger privateNCacheLog;
public final ILogger getNCacheLog()
{
return privateNCacheLog;
}
public final void setNCacheLog(ILogger value)
{
privateNCacheLog = value;
}
private String privateNCacheVersion;
public final String getNCacheVersion()
{
return privateNCacheVersion;
}
public final void setNCacheVersion(String value)
{
privateNCacheVersion = value;
}
private Map privateSystemMetricsDictionary;
public final Map getSystemMetricsDictionary()
{
return privateSystemMetricsDictionary;
}
public final void setSystemMetricsDictionary(Map value)
{
privateSystemMetricsDictionary = value;
}
public MetricsPublisher(MetricsTransporterFactory factory, PublisherContextMetaPublisher contextMetaPublisher)
{
setNCacheVersion("5.1");//Version.GetVersion();
factoryInstance = factory;
_contextMetaPublisher = contextMetaPublisher;
}
private void InitializedTrasnpoter() throws Exception {
if(_transporter == null)
_transporter = factoryInstance.Create();
if(_transporter !=null && !_transporter.getIsConnected())
{
if(serviceBindedIp == null){
try {
loadLocalServerIp();
} catch (ConfigurationException e) {
}
}
_transporter.Connect(serviceBindedIp);
}
}
public final void Initialize(){
try {
if (new MonitoringConfigManager().getCongigFile()) {
StartGatheringData();
StartPublishingData();
}
else{
throw new Exception("monitoring.ncconf not found");
}
}catch (Exception e)
{
if(getNCacheLog()!=null)
getNCacheLog().Error("Monitoring module",e.getMessage());
}
}
public final boolean RegisterMonitorableEntity(MonitorableEntity monitorableEntity)
{
synchronized (_mutex)
{
try
{
MonitoringEntityType type = monitorableEntity.getGetEntityType();
ArrayList entities = new ArrayList();
if (!((entities = _monitorableEntities.get(type)) != null))
{
ArrayList entityList = new ArrayList();
entityList.add(monitorableEntity);
_monitorableEntities.put(type, entityList);
}
if (entities != null)
{
entities.add(monitorableEntity);
}
return true;
}
catch (RuntimeException ex)
{
if(getNCacheLog()!=null)
{
getNCacheLog().Error("Monitoring Module", ex.toString());
}
return false;
}
}
}
///#region Data Collection
public final void StartGatheringData()
{
if (_dataCollector == null)
{
_dataCollector = new Thread(new Runnable() {
@Override
public void run() {
PerformDataCollection();
}
});
_dataCollector.setDaemon(true);
_dataCollector.start();
}
}
public final void StopGatheringData()
{
if (_dataCollector != null && _dataCollector.isAlive())
{
stopPublishing= true;
_dataCollector.interrupt();
}
}
private void PerformDataCollection()
{
try
{
while (!stopPublishing)
{
try
{
for (Map.Entry> registeredEntities : _monitorableEntities.entrySet())
{
switch (registeredEntities.getKey())
{
case Stats:
ProcessCounterStats(registeredEntities.getValue());
StoreStats();
break;
case APILogs:
break;
case Events:
break;
case ClusterHealth:
break;
}
}
Thread.sleep(1000);
//iterate through each monitorable entity
//1. call their native Data
//2. you may need to merge
// store data into monitorablestore
// sleep for 1 sec
}
catch (InterruptedException e)
{
stopPublishing = true;
break;
}
catch (ThreadDeath e2)
{
break;
}
catch (RuntimeException ex)
{
if (getNCacheLog() != null)
{
getNCacheLog().Error("Data Collector", ex.toString());
}
}
}
}
catch (RuntimeException ex)
{
if (getNCacheLog() != null)
{
getNCacheLog().Error("Data Collector", ex.toString());
}
}
}
//entity.publishertype==ncacheclient
private void ProcessCounterStats(ArrayList registeredEntities)
{
for (MonitorableEntity entity : registeredEntities)
{
if (_metaDataRequired && entity.getIsPrimary())
{
CollectCountersMetadata(entity);
_metaDataRequired = false;
}
CollectCounterData((CounterMonitorableEntity)entity);
}
}
private void StoreStats()
{
IntervalCounterDataCollection intervalCollection = MergeDataFromModules();
_entitiesDataStore.AddCounterData(intervalCollection);
}
private IntervalCounterDataCollection MergeDataFromModules()
{
HashMap data = new HashMap();
boolean fromreplica = false;
Publisher publisher = Publisher.NCacheClient;
Date dateTime = new Date(0);
String instanceName = null;
try
{
for (IntervalCounterDataCollection intCollection : _intervalCounterCollection)
{
for (Map.Entry val : intCollection.getValues().entrySet())
{
if (!data.containsKey(val.getKey()))
{
data.put(val.getKey(), val.getValue());
}
}
dateTime = intCollection.getTimestamp();
fromreplica = intCollection.getFromReplica();
publisher = intCollection.getPublisherType();
instanceName = intCollection.getInstanceName();
}
for (Short id : _counterIdMap.getCounterIds())
{
if (!data.containsKey(id))
{
data.put(id, -10.00);
}
}
_intervalCounterCollection.clear();
IntervalCounterDataCollection tempVar = new IntervalCounterDataCollection();
tempVar.setValues(data);
tempVar.setTimestamp(dateTime);
tempVar.setFromReplica(fromreplica);
tempVar.setPublisherType(publisher);
tempVar.setInstanceName(instanceName);
return tempVar;
}
catch (RuntimeException ex)
{
if (getNCacheLog() != null)
{
getNCacheLog().Error("Monitoring Module", ex.getMessage());
}
throw ex;
}
}
private void CollectCounterData(CounterMonitorableEntity entity)
{
try
{
if (_metaDataRequired)
{
return;
}
IntervalCounterDataCollection dataCollection = entity.getData();
CollectSystemCounterData(dataCollection);
_intervalCounterCollection.add(dataCollection);
}
catch (RuntimeException ex)
{
if (getNCacheLog() != null)
{
getNCacheLog().Error("Monitoring Module", ex.toString());
}
throw ex;
}
}
private void CollectSystemCounterData(IntervalCounterDataCollection dataCollection)
{
try
{
if (_systemMetricsDictionary != null && _systemMetricsDictionary.size() != 0)
{
for (Map.Entry item : _systemMetricsDictionary.entrySet())
{
dataCollection.getValues().put(_counterIdMap.getCounterID(item.getKey()), item.getValue().Collectstats());
}
}
}
catch (RuntimeException ex)
{
if (getNCacheLog() != null)
{
getNCacheLog().Error("Monitoring Module", ex.toString());
}
throw ex;
}
}
private void CollectSystemCountersMetadata(CounterMetadataCollection counterMetadata)
{
if (_systemMetricsDictionary != null && _systemMetricsDictionary.size() != 0)
{
for (Map.Entry item : _systemMetricsDictionary.entrySet())
{
CounterMetadata tempVar = new CounterMetadata();
tempVar.setName(item.getKey());
tempVar.setType(CounterType.RateOfCounter);
tempVar.setDescription(item.getValue().getName());
tempVar.setCategory(counterMetadata.getCategory());
counterMetadata.getCounters().add(tempVar);
}
}
}
private void CollectCountersMetadata(MonitorableEntity monitorableEntity)
{
CounterMonitorableEntity entity = (CounterMonitorableEntity)monitorableEntity;
setCounterMetadataCollection(entity.getMetadata());
if (entity.getPublisherType() == Publisher.NCacheClient)
{
getCounterMetadataCollection().setCacheConfigID(getCacheConfigID());
}
CollectSystemCountersMetadata(getCounterMetadataCollection());
if (getCounterMetadataCollection() == null)
{
if (getNCacheLog() != null)
{
getNCacheLog().Error("Monitoring Module", "Meta info is not populated.");
}
throw new RuntimeException("No meta info is added.");
}
_counterIdMap = new CounterIDMap();
_counterIdMap.assignAndAddCounters(getCounterMetadataCollection().getCounters());
}
///#endregion
///#region Publishing Data
public final void StartPublishingData()
{
if (_dataPublisher == null)
{
_dataPublisher = new Thread(new Runnable() {
@Override
public void run() {
PublishData();
}
}) ;
_dataPublisher.setDaemon(true);
_dataPublisher.start();
}
}
public final void StopPublishingData()
{
if (_dataPublisher != null && _dataPublisher.isAlive())
{
stopPublishing = true;
_dataPublisher.interrupt();
}
}
private void UpdateWaitTime()
{ if(getIntervalTime()>0)
{
long addititionalTime = (long) ((Math.pow(_increment,getIncrementPercentage())));
setIntervalTime(addititionalTime + getIncrementPercentage());
_increment++;
}
}
private void ResetWaitInterval()
{
setIntervalTime(_resetWaitTime);
}
private void PublishData()
{
while (!stopPublishing)
{
try
{
if(stopPublishing) break;
InitializedTrasnpoter();
Thread.sleep(ServiceConfiguration.getMetricsMonitorPublishingInterval().getTotalMiliSeconds());
ResetWaitInterval();
if(stopPublishing) break;
PublishMetadata();
PublishCounterData();
//PublishAPILogs();
//PublishEvents();
//Let's see if we use Push based approch
//PublishCacheHealthData();
//sleep for a configurable interval ;default 1 sec
}
catch ( InterruptedException e)
{
stopPublishing= true;
if(_transporter !=null )
_transporter.dispose();
break;
}
catch (Exception ex)
{
try {
Thread.sleep(getIntervalTime()*1000);
} catch (InterruptedException e) {
break;
}
UpdateWaitTime();
if (getNCacheLog() != null)
{
MetricsException metricsException = new MetricsException();
if (!((metricsException = _exceptionLogger.get(ex.getClass().toString())) != null))
{
MetricsException tempVar = new MetricsException();
tempVar.setTimeStamp(NCDateTime.getUTCNow());
tempVar.setException(ex);
tempVar.setLastLogTime(NCDateTime.getUTCNow());
_exceptionLogger.put(ex.getClass().toString(), tempVar);
if (getNCacheLog() != null)
{
getNCacheLog().Error("Metrics Publisher", ex.toString());
}
}
else
{
metricsException = _exceptionLogger.get(ex.getClass().toString());
metricsException.setTimeStamp(NCDateTime.getUTCNow());
metricsException.setException(ex);
if (metricsException.CompareAndUpdateifRequired())
{
if (getNCacheLog() != null)
{
getNCacheLog().Error("Metrics Publisher", ex.toString());
}
metricsException.setLastLogTime(NCDateTime.getUTCNow());
}
}
}
}
}
}
private void PublishMetadata() throws Exception {
if (_publishMetadata )
{
// this method call is responsible for send metadata of counter publisher entries
// such as caches, bridges, client, bridge caches, clients
_contextMetaPublisher.PublishMetadata(_transporter);
// this method call is responsible for send metadata of counters publish againts the above entities.
if (_metaDataRequired == false)
{
_transporter.PublishMetadata(getSessionId(), getCounterMetadataCollection());
}
_publishMetadata = false;
}
}
private void PublishCounterData() throws Exception {
if (_publishMetadata)
{
return;
}
long refStartTime = startTime;
RefObject tempRef_refStartTime = new RefObject(refStartTime);
ArrayList dataToBePublished = _entitiesDataStore.GetStatsData(tempRef_refStartTime);
refStartTime = tempRef_refStartTime.argvalue;
if (dataToBePublished != null && dataToBePublished.size() > 0)
{
boolean isReplica = false; //firstElement.FromReplica;
CounterDataCollection tempVar = new CounterDataCollection();
tempVar.setValues(dataToBePublished);
tempVar.setVersion(getNCacheVersion());
tempVar.setCategory(getCounterMetadataCollection().getCategory());
tempVar.setInstanceName(getCounterMetadataCollection().getInstanceName());
tempVar.setFromReplica(getCounterMetadataCollection().getFromReplica());
tempVar.setCacheUniqueID(Long.toString(ProcessHandle.current().pid()));
CounterDataCollection counterDataCollection = tempVar;
PublishCountersDataResult result = _transporter.PublishData(getSessionId(), counterDataCollection);
if(result == PublishCountersDataResult.CountersSessionExpired || result == PublishCountersDataResult.CountersMetaDataNotPersisted){
_publishMetadata = true;
}
startTime = refStartTime;
}
//var firstElement = dataToBePublished.FirstOrDefault();
}
public final void dispose()
{
stopPublishing= true;
StopGatheringData();
StopPublishingData();
if(_entitiesDataStore !=null)
{
try {
_entitiesDataStore.close();
} catch (Exception e) {
}
}
if (_transporter != null)
{
_transporter.dispose();
}
_contextMetaPublisher = null;
}
public void loadLocalServerIp() throws ConfigurationException {
this.serviceBindedIp = AppUtil.getLocalServerIp();
}
}