Java tutorial
/** * Copyright ${year} imperial * Contact: imperial <weikun.wang11@imperial.ac.uk> * * Licensed under the BSD 3-Clause License (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package imperial.modaclouds.monitoring.datacollectors.monitors; import freemarker.core.ParseException; import imperial.modaclouds.monitoring.datacollectors.basic.AbstractMonitor; import imperial.modaclouds.monitoring.datacollectors.basic.Config; import imperial.modaclouds.monitoring.datacollectors.basic.ConfigurationException; import it.polimi.tower4clouds.data_collector_library.DCAgent; import it.polimi.tower4clouds.model.ontology.VM; import java.io.FileNotFoundException; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.cloudwatch.AmazonCloudWatchClient; import com.amazonaws.services.cloudwatch.model.Datapoint; import com.amazonaws.services.cloudwatch.model.Dimension; import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsRequest; import com.amazonaws.services.cloudwatch.model.GetMetricStatisticsResult; /** * The monitoring collector for cost on EC2. */ public class CostMonitor extends AbstractMonitor { private Logger logger = LoggerFactory.getLogger(CostMonitor.class); /** * CloudWatch monitor thread. */ private Thread cwmt; /** * Amazon CloudWatch client. */ private AmazonCloudWatchClient cloudWatchClient; /** * Monitoring period. */ private int period; /** * The unique monitored target. */ private String monitoredTarget; /** * The sampling probability. */ private double samplingProb; private DCAgent dcAgent; /** * The measure set to store the monitoring value. */ private static class MeasureSet implements Comparable<MeasureSet> { public Calendar timestamp; public HashMap<String, Double> measures = new HashMap<String, Double>(); @Override public int compareTo(MeasureSet compare) { return (int) (timestamp.getTimeInMillis() - compare.timestamp.getTimeInMillis()); } public void setMeasure(String measureName, double value) { measures.put(measureName, value); } public Set<String> getMeasureNames() { return measures.keySet(); } public double getMeasure(String measureName) { return measures.get(measureName); } } /** * Constructor of the class. * @throws MalformedURLException * @throws FileNotFoundException */ public CostMonitor(String resourceId, String mode) { //this.monitoredResourceID = "FrontendVM"; //this.monitoredTarget = monitoredResourceID; super(resourceId, mode); monitoredTarget = resourceId; monitorName = "cost"; } @Override public void run() { String accessKeyId = null; String secretKey = null; ArrayList<String> measureNames = null; long startTime = 0; while (!cwmt.isInterrupted()) { if (System.currentTimeMillis() - startTime > 10000) { measureNames = new ArrayList<String>(); for (String metric : getProvidedMetrics()) { try { VM resource = new VM(Config.getInstance().getVmType(), Config.getInstance().getVmId()); if (dcAgent.shouldMonitor(resource, metric)) { Map<String, String> parameters = dcAgent.getParameters(resource, metric); measureNames.add("EstimatedCharges"); accessKeyId = parameters.get("accessKey"); secretKey = parameters.get("secretKey"); period = Integer.valueOf(parameters.get("samplingTime")) * 1000; samplingProb = Double.valueOf(parameters.get("samplingProbability")); } } catch (NumberFormatException | ConfigurationException e) { e.printStackTrace(); } } cloudWatchClient = new AmazonCloudWatchClient(new BasicAWSCredentials(accessKeyId, secretKey)); cloudWatchClient.setEndpoint("monitoring.us-east-1.amazonaws.com"); startTime = System.currentTimeMillis(); } MeasureSet measureSet = null; try { measureSet = this.retrieveMeasureSet(measureNames); } catch (ParseException e) { e.printStackTrace(); } if (measureSet != null) { for (String measureName : measureSet.getMeasureNames()) { try { if (Math.random() < samplingProb) { logger.info("Sending datum: {} {} {}", measureSet.getMeasure(measureName), "Cost", monitoredTarget); dcAgent.send(new VM(Config.getInstance().getVmType(), Config.getInstance().getVmId()), "Cost", measureSet.getMeasure(measureName)); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } //System.out.println(measureName+" "+String.valueOf(measureSet.getMeasure(measureName))); //measure.push(measureName, String.valueOf(measureSet.getMeasure(measureName)),"EC2"); } } try { Thread.sleep(period); } catch (InterruptedException e) { Thread.currentThread().interrupt(); break; } } } private Set<String> getProvidedMetrics() { Set<String> metrics = new HashSet<String>(); metrics.add("GeneralCost"); return metrics; } /** * Retrieve monitoring value from metric names. */ public MeasureSet retrieveMeasureSet(ArrayList<String> measureNames) throws ParseException { GetMetricStatisticsRequest getMetricRequest = new GetMetricStatisticsRequest(); // Dimension Set ArrayList<Dimension> dimensions = new ArrayList<Dimension>(); Dimension dim = new Dimension(); //dim.setName("InstanceId"); //dim.setValue(instanceID); dim.setName("Currency"); dim.setValue("USD"); dimensions.add(dim); // Time Set //TimeZone zone = TimeZone.getDefault(); //int timeOffset = zone.getOffset(new Date().getTime()) / (1000 * 3600); //String dateFormatString = "%1$tY-%1$tm-%1$tdT%1tH:%1$tM:%1$tSZ"; GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); calendar.add(GregorianCalendar.SECOND, -1 * calendar.get(GregorianCalendar.SECOND)); // Static Set ArrayList<String> stats = new ArrayList<String>(); stats.add("Average"); //stats.add("Maximum"); getMetricRequest.setStatistics(stats); getMetricRequest.setNamespace("AWS/Billing"); getMetricRequest.setPeriod(3600); getMetricRequest.setDimensions(dimensions); getMetricRequest.setEndTime(calendar.getTime()); calendar.add(GregorianCalendar.HOUR, -10); getMetricRequest.setStartTime(calendar.getTime()); HashMap<Long, MeasureSet> measureSets = new HashMap<Long, MeasureSet>(); for (String measureName : measureNames) { getMetricRequest.setMetricName(measureName); GetMetricStatisticsResult metricStatistics = cloudWatchClient.getMetricStatistics(getMetricRequest); List<Datapoint> datapoints = metricStatistics.getDatapoints(); for (Datapoint point : datapoints) { Calendar cal = new GregorianCalendar(); cal.setTime(point.getTimestamp()); //cal.add(GregorianCalendar.HOUR, timeOffset); MeasureSet measureSet = measureSets.get(cal.getTimeInMillis()); if (measureSet == null) { measureSet = new MeasureSet(); measureSet.timestamp = cal; measureSets.put(cal.getTimeInMillis(), measureSet); } measureSet.setMeasure(measureName, point.getAverage()); } } ArrayList<MeasureSet> sortedMeasureSets = new ArrayList<MeasureSet>(measureSets.values()); if (sortedMeasureSets.size() == 0) { return null; } else { Collections.sort(sortedMeasureSets); return sortedMeasureSets.get(sortedMeasureSets.size() - 1); } } public void start() { cwmt = new Thread(this, "cwm-mon"); } @Override public void init() { cwmt.start(); System.out.println("Cost monitor running!"); } @Override public void stop() { while (!cwmt.isInterrupted()) { cwmt.interrupt(); } System.out.println("Cost monitor stopped!"); } @Override public void setDCAgent(DCAgent dcAgent) { this.dcAgent = dcAgent; } }