Java tutorial
/* * Copyright 2010-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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 com.github.lpezet.antiope.metrics.aws; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.DaemonThreadCount; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.DeadLockThreadCount; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.FreeMemory; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.OpenFileDescriptorCount; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.PeakThreadCount; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.SpareFileDescriptorCount; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.SpareMemory; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.ThreadCount; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.TotalMemory; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.TotalStartedThreadCount; import static com.github.lpezet.antiope.metrics.aws.MachineMetric.UsedMemory; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.apache.commons.logging.LogFactory; import com.amazonaws.jmx.spi.JmxInfoProvider; import com.amazonaws.services.cloudwatch.model.Dimension; import com.amazonaws.services.cloudwatch.model.MetricDatum; import com.amazonaws.services.cloudwatch.model.StandardUnit; import com.github.lpezet.antiope.metrics.MetricType; class MachineMetricFactory { private static final List<MachineMetric> MEMORY_METRICS = Arrays.asList(TotalMemory, FreeMemory, UsedMemory, SpareMemory); private static final List<MachineMetric> THREAD_METRICS = Arrays.asList(ThreadCount, DeadLockThreadCount, DaemonThreadCount, PeakThreadCount, TotalStartedThreadCount); private static final List<MachineMetric> FD_METRICS = Arrays.asList(OpenFileDescriptorCount, SpareFileDescriptorCount); private final JmxInfoProvider mJmxInfoProvider = JmxInfoProvider.Factory.getJmxInfoProvider(); private Config mConfig; public MachineMetricFactory(Config pConfig) { mConfig = pConfig; } /** * Add the given list of metrics and corresponding values specified in * "metricValues" to the given list of metric datum. * * @param pList * list of metric data * @param pMetricValues * list of metrics and their corresponding values */ private void addMetrics(List<MetricDatum> pList, MetricValues pMetricValues, StandardUnit pUnit) { List<MachineMetric> oMachineMetrics = pMetricValues.getMetrics(); List<Long> oValues = pMetricValues.getValues(); for (int i = 0; i < oMachineMetrics.size(); i++) { MachineMetric oMetric = oMachineMetrics.get(i); long val = oValues.get(i).longValue(); // skip zero values in some cases if (val != 0 || oMetric.includeZeroValue()) { MetricDatum oDatum = new MetricDatum().withMetricName(oMetric.getMetricName()) .withDimensions( new Dimension().withName(oMetric.getDimensionName()).withValue(oMetric.name())) .withUnit(pUnit).withValue((double) val); pList.add(oDatum); } } } /** * Returns the set of custom machine metrics specified in the SDK metrics * registry; or an empty set if there is none. Note any machine metrics * found in the registry must have been custom specified, as the default * behavior is to include all machine metrics when enabled. * * @return a non-null set of machine metrics. An empty set means no custom * machine metrics have been specified. */ private Set<MachineMetric> customMachineMetrics() { Set<MachineMetric> oCustomized = new HashSet<MachineMetric>(); for (MetricType m : mConfig.getMetricsConfig().getPredefinedMetrics()) { if (m instanceof MachineMetric) oCustomized.add((MachineMetric) m); } return oCustomized; } /** * Returns a subset of the given list of metrics in "defaults" and the * corresponding value of each returned metric in the subset. Note if the * custom set is empty, the full set of default machine metrics and values * will be returned. (In particular, as in set theory, a set is a subset of * itself.) * * @param pCustomSet * custom machine metrics specified in the SDK metrics registry * @param pDefaults * the given default list of metrics * @param pValues * corresponding values of each metric in "defaults" */ private MetricValues metricValues(Set<MachineMetric> pCustomSet, List<MachineMetric> pDefaults, List<Long> pValues) { List<MachineMetric> oActualMetrics = pDefaults; List<Long> oActualValues = pValues; if (pCustomSet.size() > 0) { // custom set of machine metrics specified oActualMetrics = new ArrayList<MachineMetric>(); oActualValues = new ArrayList<Long>(); for (int i = 0; i < pDefaults.size(); i++) { MachineMetric mm = pDefaults.get(i); if (pCustomSet.contains(mm)) { oActualMetrics.add(mm); oActualValues.add(pValues.get(i)); } } } return new MetricValues(oActualMetrics, oActualValues); } List<MetricDatum> generateMetrics() { if (mConfig.getMetricsConfig().isMachineMetricExcluded()) return Collections.emptyList(); Set<MachineMetric> oCustomSet = customMachineMetrics(); List<MetricDatum> oTargetList = new ArrayList<MetricDatum>(MachineMetric.values().length); // Memory usage addMemoryMetrics(oTargetList, oCustomSet); // Thread related counts try { addThreadMetrics(oTargetList, oCustomSet); } catch (Throwable t) { LogFactory.getLog(getClass()).debug("Ignoring thread metrics", t); } // File descriptor usage try { addFileDescriptorMetrics(oTargetList, oCustomSet); } catch (Throwable t) { LogFactory.getLog(getClass()).debug("Ignoring file descriptor metrics", t); } return oTargetList; } private void addMemoryMetrics(List<MetricDatum> pTargetList, Set<MachineMetric> pCustomSet) { Runtime rt = Runtime.getRuntime(); long oTotalMem = rt.totalMemory(); long oFreeMem = rt.freeMemory(); long oUsedMem = oTotalMem - oFreeMem; long oSpareMem = rt.maxMemory() - oUsedMem; List<Long> oValues = Arrays.asList(oTotalMem, oFreeMem, oUsedMem, oSpareMem); MetricValues oMetricValues = memoryMetricValues(pCustomSet, oValues); addMetrics(pTargetList, oMetricValues, StandardUnit.Bytes); } private void addFileDescriptorMetrics(List<MetricDatum> pTargetList, Set<MachineMetric> pCustomSet) { JmxInfoProvider oProvider = JmxInfoProvider.Factory.getJmxInfoProvider(); long[] oFdInfo = oProvider.getFileDecriptorInfo(); if (oFdInfo != null) { long oOpenFdCount = oFdInfo[0]; long oMaxFdCount = oFdInfo[1]; List<Long> oValues = Arrays.asList(oOpenFdCount, oMaxFdCount - oOpenFdCount); MetricValues oMetricValues = fdMetricValues(pCustomSet, oValues); addMetrics(pTargetList, oMetricValues, StandardUnit.Count); } } private void addThreadMetrics(List<MetricDatum> pTargetList, Set<MachineMetric> pCustomSet) { long oThreadCount = mJmxInfoProvider.getThreadCount(); long[] oIds = mJmxInfoProvider.findDeadlockedThreads(); long oDeadLockThreadCount = oIds == null ? 0 : oIds.length; long oDaemonThreadCount = mJmxInfoProvider.getDaemonThreadCount(); long oPeakThreadCount = mJmxInfoProvider.getPeakThreadCount(); long oTotalStartedThreadCount = mJmxInfoProvider.getTotalStartedThreadCount(); List<Long> oValues = Arrays.asList(oThreadCount, oDeadLockThreadCount, oDaemonThreadCount, oPeakThreadCount, oTotalStartedThreadCount); MetricValues oMetricValues = threadMetricValues(pCustomSet, oValues); addMetrics(pTargetList, oMetricValues, StandardUnit.Count); } /** * Returns the set of memory metrics and the corresponding values based on * the default and the customized set of metrics, if any. * * @param pCustomSet * a non-null customized set of metrics * @param pValues * a non-null list of values corresponding to the list of default * memory metrics */ private MetricValues memoryMetricValues(Set<MachineMetric> pCustomSet, List<Long> pValues) { return metricValues(pCustomSet, MachineMetricFactory.MEMORY_METRICS, pValues); } /** * Returns the set of file-descriptor metrics and the corresponding values based on * the default and the customized set of metrics, if any. * * @param pCustomSet * a non-null customized set of metrics * @param pValues * a non-null list of values corresponding to the list of default * file-descriptor metrics */ private MetricValues fdMetricValues(Set<MachineMetric> pCustomSet, List<Long> pValues) { return metricValues(pCustomSet, MachineMetricFactory.FD_METRICS, pValues); } /** * Returns the set of thread metrics and the corresponding values based on * the default and the customized set of metrics, if any. * * @param pCustomSet * a non-null customized set of metrics * @param pValues * a non-null list of values corresponding to the list of default * thread metrics */ private MetricValues threadMetricValues(Set<MachineMetric> pCustomSet, List<Long> pValues) { return metricValues(pCustomSet, MachineMetricFactory.THREAD_METRICS, pValues); } // Used to get around the limitation of Java returning at most a single value private static class MetricValues { private final List<MachineMetric> mMetrics; private final List<Long> mValues; MetricValues(List<MachineMetric> pMetrics, List<Long> pValues) { this.mMetrics = pMetrics; this.mValues = pValues; } List<MachineMetric> getMetrics() { return mMetrics; } List<Long> getValues() { return mValues; } } }