/******************************************************************************* * ALMA - Atacama Large Millimeter Array * Copyright (c) ESO - European Southern Observatory, 2011 * (in the framework of the ALMA collaboration). * All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *******************************************************************************/ package alma.acs.service; import gov.sandia.CosNotification.NotificationServiceMonitorControl; import gov.sandia.CosNotification.NotificationServiceMonitorControlPackage.InvalidName; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.List; //import java.util.logging.Logger; import alma.acs.exceptions.AcsJException; //import alma.acs.logging.AcsLogLevel; import alma.acs.nsstatistics.ChannelData; class ChannelStats { static final String N_CONSUMERS = "n. consumers"; static final String N_SUPPLIERS = "n. suppliers"; static final String N_SLOWEST_CONSUMERS = "n. slowest consumers"; static final String N_SUPPLIERS_ADMIN = "n. suppliers admin"; static final String N_CONSUMERS_ADMIN = "n. consumers admin"; static final String CURR_SLOWEST_CONSUMERS = "Current slowest consumers"; static final String CURR_CONSUMERS = "Current consumers"; static final String CURR_SUPPLIERS = "Current suppliers"; static final String CURR_CONSUMERS_ADMIN = "Current consumers admin"; static final String CURR_SUPPLIERS_ADMIN = "Current consumers admin"; static final String ALL_SLOWEST_CONSUMERS = "All slowest consumers"; static final String ALL_CONSUMERS = "All consumers"; static final String ALL_SUPPLIERS = "All suppliers"; static final String ALL_CONSUMERS_ADMIN = "All consumers admin"; static final String ALL_SUPPLIERS_ADMIN = "All consumers admin"; class AggregateData { public long max; public long min; public float avg; public long sum; public AggregateData() { max = 0; min = 0; avg = 0; sum = 0; } public AggregateData(long value) { max = value; min = value; avg = (float)value; sum = value; } public void set(long value, long counter) { if(max < value || counter == 0) { max = value; } if(min > value || counter == 0) { min = value; } sum += value; avg = sum / (counter + 1); } public String toString() { return "MIN=" + String.valueOf(min) + ", MAX=" + String.valueOf(max) + ", AVG=" + String.valueOf(avg); } } private HashMap<String, AggregateData> aggregateData; private HashMap<String, ArrayList<String>> currStringLists; // Current slowest consumers, consumers, suppliers, consumers admin, suppliers admin private HashMap<String, ArrayList<String>> allStringLists; // All slowest consumers, consumers, suppliers, consumers admin, suppliers admin private HashMap<String, AggregateData> queuesElementCount; // key: Queue name private HashMap<String, AggregateData> queuesSize; // key: Queue name private HashMap<String, Double> queuesSizeAvg; // key: Queue name private HashMap<String, Long> queuesSizeMax; // key: Queue name private long oldestEvent; public long counter; ChannelStats() { aggregateData = new HashMap<String, AggregateData>(); currStringLists = new HashMap<String, ArrayList<String>>(); allStringLists = new HashMap<String, ArrayList<String>>(); queuesElementCount = new HashMap<String, AggregateData>(); queuesSize = new HashMap<String, AggregateData>(); queuesSizeAvg = new HashMap<String, Double>(); queuesSizeMax = new HashMap<String, Long>(); oldestEvent = -1; counter = 0; } public void reset() { counter = 0; aggregateData.clear(); currStringLists.clear(); allStringLists.clear(); queuesElementCount.clear(); queuesSize.clear(); queuesSizeAvg.clear(); queuesSizeMax.clear(); oldestEvent = -1; } public void setData(ChannelData channel) { NotificationServiceMonitorControl nsm = channel.getParent().getMc(); String [] statsNames = nsm.get_statistic_names(); String channelName = "Channel " + channel.getName() + " - "; long oldestEvent = -1; for(int i = 0;i < statsNames.length;++i) { try { if(statsNames[i].contains("ConsumerCount")) { Monitor.Numeric n = nsm.get_statistic(statsNames[i]).data_union.num(); setValue(N_CONSUMERS, (long)n.last); } else if(statsNames[i].contains("SupplierCount")) { Monitor.Numeric n = nsm.get_statistic(statsNames[i]).data_union.num(); setValue(N_SUPPLIERS, (long)n.last); } else if(statsNames[i].contains("QueueSize")) { // n.count, n.maximum, n.last, n.average, n.dlist[0].value, n.dlist[0].timestamp Monitor.Numeric n = nsm.get_statistic(statsNames[i]).data_union.num(); setQueueSize(statsNames[i], (long)n.maximum, n.average); } else if(statsNames[i].contains("QueueElementCount")) { Monitor.Numeric n = nsm.get_statistic(statsNames[i]).data_union.num(); setQueueElementCount(statsNames[i], (long)n.maximum); } else if(statsNames[i].contains("OldestEvent")) { Monitor.Numeric n = nsm.get_statistic(statsNames[i]).data_union.num(); this.oldestEvent = (long)n.last; } else if(statsNames[i].contains("SlowestConsumers")) { String [] slowestConsumers = nsm.get_statistic(statsNames[i]).data_union.list(); setArrayValues(CURR_SLOWEST_CONSUMERS, currStringLists, slowestConsumers); addArrayValues(ALL_SLOWEST_CONSUMERS, allStringLists, slowestConsumers); setValue(N_SLOWEST_CONSUMERS, slowestConsumers.length); } else if(statsNames[i].contains("SupplierNames")) { String [] supplierNames = nsm.get_statistic(statsNames[i]).data_union.list(); setArrayValues(CURR_SUPPLIERS, currStringLists, supplierNames); addArrayValues(ALL_SUPPLIERS, allStringLists, supplierNames); } else if(statsNames[i].contains("ConsumerNames")) { String [] consumerNames = nsm.get_statistic(statsNames[i]).data_union.list(); setArrayValues(CURR_CONSUMERS, currStringLists, consumerNames); addArrayValues(ALL_CONSUMERS, allStringLists, consumerNames); } else if(statsNames[i].contains("SupplierAdminNames")) { String [] supplierAdminNames = nsm.get_statistic(statsNames[i]).data_union.list(); setArrayValues(CURR_SUPPLIERS_ADMIN, currStringLists, supplierAdminNames); addArrayValues(ALL_SUPPLIERS_ADMIN, allStringLists, supplierAdminNames); setValue(N_SUPPLIERS_ADMIN, supplierAdminNames.length); } else if(statsNames[i].contains("ConsumerAdminNames")) { String [] consumerAdminNames = nsm.get_statistic(statsNames[i]).data_union.list(); setArrayValues(CURR_CONSUMERS_ADMIN, currStringLists, consumerAdminNames); addArrayValues(ALL_CONSUMERS_ADMIN, allStringLists, consumerAdminNames); setValue(N_CONSUMERS_ADMIN, consumerAdminNames.length); } } catch(InvalidName ex) { //logger.log(AcsLogLevel.ERROR, "Invalid name in ncStatisticsService::logMCStats", ex); // TODO } } iterationDone(); } protected void setArrayValues(String key,HashMap<String,ArrayList<String>> data,String [] values) { ArrayList<String> array = new ArrayList<String>(); for(int i = 0;i < values.length;++i) { array.add(values[i]); } data.put(key, array); } protected void setQueueElementCount(String name,long value) { int i = name.indexOf("QueueElementCount"); String queueName = name.substring(0, i); AggregateData data = queuesElementCount.get(queueName); if(null == data) { data = new AggregateData(value); } else { data.set(value, counter); } queuesElementCount.put(queueName, data); } protected void setQueueSize(String name,long value,double average) { int i = name.indexOf("QueueSize"); String queueName = name.substring(0, i); AggregateData data = queuesSize.get(queueName); if(null == data) { data = new AggregateData(value); } else { data.set(value, counter); } queuesSize.put(queueName, data); Double lastAvg = queuesSizeAvg.get(queueName); if(lastAvg == null) { queuesSizeAvg.put(queueName, new Double(average)); } else { queuesSizeAvg.put(queueName, lastAvg + average); } Long lastMax = queuesSizeMax.get(queueName); if(lastMax == null || lastMax < value) { queuesSizeMax.put(queueName, new Long(value)); } } protected void addArrayValues(String key,HashMap<String,ArrayList<String>> data,String [] values) { ArrayList<String> array = null; if(false == data.containsKey(key)) { array = new ArrayList<String>(); } else { array = data.get(key); } for(int i = 0;i < values.length;++i) { if(false == array.contains(values[i])) { array.add(values[i]); } } data.put(key, array); } public void setValue(String key,long value) { AggregateData data = null; if(0 == counter) { data = new AggregateData(value); } else { data = aggregateData.get(key); if(null == data) { data = new AggregateData(value); } else { data.set(value, counter); } } aggregateData.put(key, data); } public Long getMaxValue(String key) { if(0 == counter) { return null; } AggregateData data = aggregateData.get(key); if(null == data) { return null; } return data.max; } public Long getMinValue(String key) { if(0 == counter) { return null; } AggregateData data = aggregateData.get(key); if(null == data) { return null; } return data.min; } public Float getAvgValue(String key) { if(0 == counter) { return null; } AggregateData data = aggregateData.get(key); if(null == data) { return null; } return data.avg; } public long iterationDone() { counter++; return counter; } public Map<String,String> getDbgParams() { Map<String,String> dbgParams = new HashMap<String,String>(); String str = ""; AggregateData data = null; ArrayList<String> strList = null; data = aggregateData.get(N_CONSUMERS); dbgParams.put("Num consumers",data.toString()); data = aggregateData.get(N_SUPPLIERS); dbgParams.put("Num suppliers",data.toString()); data = aggregateData.get(N_SLOWEST_CONSUMERS); dbgParams.put("Num slowest consumers",data.toString()); data = aggregateData.get(N_CONSUMERS_ADMIN); dbgParams.put("Num consumers admin",data.toString()); data = aggregateData.get(N_SUPPLIERS_ADMIN); dbgParams.put("Num suppliers admin",data.toString()); strList = currStringLists.get(CURR_CONSUMERS); dbgParams.put("Current consumers", array2str(strList)); strList = currStringLists.get(CURR_SUPPLIERS); dbgParams.put("Current suppliers", array2str(strList)); strList = currStringLists.get(CURR_SLOWEST_CONSUMERS); dbgParams.put("Current slowest consumers", array2str(strList)); strList = currStringLists.get(CURR_CONSUMERS_ADMIN); dbgParams.put("Current consumers admin", array2str(strList)); strList = currStringLists.get(CURR_SUPPLIERS_ADMIN); dbgParams.put("Current suppliers admin", array2str(strList)); strList = allStringLists.get(ALL_CONSUMERS); dbgParams.put("All consumers", array2str(strList)); strList = allStringLists.get(ALL_SUPPLIERS); dbgParams.put("All suppliers", array2str(strList)); strList = allStringLists.get(ALL_SLOWEST_CONSUMERS); dbgParams.put("All slowest consumers", array2str(strList)); strList = allStringLists.get(ALL_CONSUMERS_ADMIN); dbgParams.put("All consumers admin", array2str(strList)); strList = allStringLists.get(ALL_SUPPLIERS_ADMIN); dbgParams.put("All suppliers admin", array2str(strList)); return dbgParams; } public Map<String,String> getInfoParams(ServiceParameters params) { Map<String,String> infoParams = new HashMap<String,String>(); String str = "", strMax = "", strAvg = ""; AggregateData data = null; ArrayList<String> strList = null; long lMax = 0; double dMax = 0; data = aggregateData.get(N_CONSUMERS); infoParams.put("Num consumers",data.toString()); data = aggregateData.get(N_SUPPLIERS); infoParams.put("Num suppliers",data.toString()); strMax = ""; strAvg = ""; lMax = 0; for(Map.Entry<String, AggregateData> entry : queuesElementCount.entrySet()) { strMax += String.valueOf(entry.getValue().max) + ", "; strAvg += String.valueOf(entry.getValue().avg) + ", "; if(entry.getValue().max > lMax) { lMax = entry.getValue().max; } } infoParams.put("Max events in queues", strMax); infoParams.put("Avg events in queues", strAvg); if(lMax >= params.getThOldestEvent()) { infoParams.put("Oldest event", String.valueOf(oldestEvent)); } str = ""; lMax = 0; for(Map.Entry<String, Long> entry : queuesSizeMax.entrySet()) { str += entry.getValue().toString() + ", "; if(entry.getValue() > lMax) { lMax = entry.getValue().longValue(); } } if(lMax >= params.getThQueueSize()) { infoParams.put("Max size of queues [bytes]", str); } str = ""; for(Map.Entry<String, Double> entry : queuesSizeAvg.entrySet()) { double avg = entry.getValue().doubleValue(); if(counter == 0) { avg = 0; } else { avg = avg / counter; } str += String.valueOf(avg) + ", "; } if(lMax >= params.getThQueueSize()) { infoParams.put("Avg size of queues [bytes]", str); } strList = currStringLists.get(CURR_SLOWEST_CONSUMERS); if(strList.size() > 0) { infoParams.put("Current slowest consumers", array2str(strList)); } strList = allStringLists.get(ALL_SLOWEST_CONSUMERS); if(strList.size() > 0) { infoParams.put("All slowest consumers", array2str(strList)); } return infoParams; } protected String array2str(List<String> list) { if(list.size() <= 0) { return ""; } String str = ""; for(int i = 0;i < list.size() - 1;++i) { str += list.get(i) + ","; } return str + list.get(list.size() - 1); } }