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

net.welen.jmole.protocols.cloudwatch.CloudWatch Maven / Gradle / Ivy

There is a newer version: 1.5.4
Show newest version
package net.welen.jmole.protocols.cloudwatch;

/*
 * #%L
 * JMole, https://bitbucket.org/awelen/jmole
 * %%
 * Copyright (C) 2015 - 2019 Anders Welén, [email protected]
 * %%
 * This program 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 3 of the
 * License, or (at your option) any later version.
 * 
 * This program 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 General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import javax.management.ObjectName;

import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
import com.amazonaws.services.cloudwatch.model.ComparisonOperator;
import com.amazonaws.services.cloudwatch.model.DeleteAlarmsRequest;
import com.amazonaws.services.cloudwatch.model.Dimension;
import com.amazonaws.services.cloudwatch.model.MetricDatum;
import com.amazonaws.services.cloudwatch.model.PutMetricAlarmRequest;
import com.amazonaws.services.cloudwatch.model.PutMetricDataRequest;
import com.amazonaws.services.cloudwatch.model.Statistic;

import net.welen.jmole.Configuration;
import net.welen.jmole.JMole;
import net.welen.jmole.collector.MBeanCollector;
import net.welen.jmole.finder.MBeanFinder;
import net.welen.jmole.presentation.PresentationInformation;
import net.welen.jmole.protocols.AbstractIntervalProtocol;
import net.welen.jmole.threshold.Threshold;
import net.welen.jmole.threshold.ThresholdValues;

public class CloudWatch extends AbstractIntervalProtocol implements CloudWatchMBean {

	private final static java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(CloudWatch.class.getName());
	
	private static final String PROPERTY_CLOUDWATCH_ENABLED = "jmole.protocol.cloudwatch.enabled";
	private static final String PROPERTY_CLOUDWATCH_NAMESPACE = "jmole.protocol.cloudwatch.namespace";
	private static final  String PROPERTY_CLOUDWATCH_INTERVAL = "jmole.protocol.cloudwatch.interval";

	private Long interval;	
	private String namespace;

	private JMole jmole;
	private AmazonCloudWatch amazonCloudWatch;
	
	private List alarmList = new ArrayList();

	@Override
	public boolean isEnabled() {
		return Boolean.getBoolean(PROPERTY_CLOUDWATCH_ENABLED);
	}

	@Override
	public void startProtocol(JMole jmole) throws Exception {
		this.jmole = jmole;

		amazonCloudWatch = AmazonCloudWatchClientBuilder.defaultClient();	
		
		interval = Long.getLong(PROPERTY_CLOUDWATCH_INTERVAL);
		if (interval == null) {
			interval = 60000L;
		}
		
		namespace = System.getProperty(PROPERTY_CLOUDWATCH_NAMESPACE);
		if (namespace == null) {
			namespace = "JMole";
		}

		createAlarms();

		super.startProtocol(jmole);
		LOG.log(Level.INFO, "JMole CloudWatch protocol started: Interval=" + interval);
	}

	@Override
	public void stopProtocol() throws Exception {
		try {
			LOG.log(Level.INFO, "Stopping JMole CloudWatch protocol");
			super.stopProtocol();
			LOG.log(Level.INFO, "JMole CloudWatch protocol stopped");
		} finally {
			 stopAlarms();
		}
	}
	
	private void createAlarms() {
		for (Configuration configuration : jmole.getConfiguration()) {
			MBeanFinder finder = configuration.getMBeanFinder();
			if (finder.getMatchingObjectNames().isEmpty()) {
				continue;
			}
			MBeanCollector collector = configuration.getMBeanCollector();
			PresentationInformation presentationInformation = configuration.getPresentationInformation();
					
			for (ObjectName objectName : finder.getMatchingObjectNames()) {
				for (String attribute : collector.getAttributes()) {
					try {
						String name = collector.getConstructedName(objectName);
						Threshold threshold = configuration.getThresholds().get(attribute);					
						if (threshold != null) {
							ThresholdValues individualValues = threshold.getIndividualThresholds().get(name);						
							
							String warnLow;
							String warnHigh;								
							String criticalLow;
							String criticalHigh;								
							
							if (individualValues == null) {
								warnLow = threshold.getWarningLowThreshold();							
								warnHigh = threshold.getWarningHighThreshold();
								criticalLow = threshold.getCriticalLowThreshold();
								criticalHigh = threshold.getCriticalHighThreshold();
							} else {
								warnLow = individualValues.getWarningLowThreshold();
								warnHigh = individualValues.getWarningHighThreshold();
								criticalLow = individualValues.getCriticalLowThreshold();
								criticalHigh = individualValues.getCriticalHighThreshold();
							}
							
							String list[] = {warnLow, warnHigh, criticalLow, criticalHigh};						
							for (String measurement : list) {
								String calculatedValue = Threshold.calculateThreshold(measurement, collector, objectName, attribute);
								if (!calculatedValue.isEmpty()) {
									
									ComparisonOperator compOper = ComparisonOperator.GreaterThanThreshold;
									if (measurement.contains("Low")) {
										compOper = ComparisonOperator.LessThanThreshold;
									}
									String type = "WARNING";
									if (measurement.contains("critical")) {
										type = "CRITICAL";
									}
									
									Dimension dimension = new Dimension()
											.withName(presentationInformation.getCategory())
											.withValue(name);

									String alarmName = presentationInformation.getCategory() +
											"/" + name + "/" +
											presentationInformation.translateAttributeLabel(attribute);
									
									String description = type + ": ";
									if (individualValues == null) {
										description += threshold.getMessage();
									} else {
										description += individualValues.getMessage();
									}
									description = String.format(description, "");
									
									PutMetricAlarmRequest request = new PutMetricAlarmRequest()
											.withAlarmName(alarmName)
											.withComparisonOperator(compOper)
											.withEvaluationPeriods(1)
											.withStatistic(Statistic.SampleCount)
											.withPeriod(60)
											.withMetricName(presentationInformation.translateAttributeLabel(attribute))
											.withAlarmDescription(description)
											.withNamespace(namespace)
											.withThreshold(Double.parseDouble(calculatedValue))
											.withActionsEnabled(false)
											.withDimensions(dimension);
	
									amazonCloudWatch.putMetricAlarm(request);
									alarmList.add(alarmName);
								}
							}						
						}
					} catch (Exception e) {
						LOG.log(Level.SEVERE, e.getMessage(), e);
					}
				}
			}		
		}
	}

	private void stopAlarms() {				
		DeleteAlarmsRequest request = new DeleteAlarmsRequest().withAlarmNames(alarmList);
		amazonCloudWatch.deleteAlarms(request);				
		alarmList.clear();
	}
	
	@Override
	public long getInterval() {
		return interval;
	}

	@Override
	public void setInterval(long interval) {
		this.interval = interval;
	}

	@Override
	public String getNamespace() {
		return namespace;
	}

	@Override
	public void setNamespace(String namespace) {
		this.namespace = namespace;
	}
	
	@Override
	protected void handleMeasurement(String category, String name, String attribute, Object value,
			PresentationInformation presentationInformation) throws Exception {
		Dimension dimension = new Dimension()
				.withName(category)
				.withValue(name);
		
		MetricDatum datum = new MetricDatum()									
				.withMetricName(presentationInformation.translateAttributeLabel(attribute))
				.withValue(Double.valueOf(value.toString()))
				.withDimensions(dimension);

		PutMetricDataRequest request = new PutMetricDataRequest()
				.withNamespace(namespace)
				.withMetricData(datum);

		amazonCloudWatch.putMetricData(request);							
	}

	@Override
	protected void handleWarnings() throws Exception {
		// Nothing to do
		LOG.fine("handleWarnings() called");
	}

	@Override
	protected void handleCriticals() throws Exception {
		// Nothing to do
		LOG.fine("handleCritical() called");
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy