All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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();
    }

    
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy