Java tutorial
/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. 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 Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.hq.measurement.galerts; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperic.hq.product.MetricValue; /** * Tracks chronologically the metrics for a given resource. */ class ResourceMetricTracker { private static final Log _log = LogFactory.getLog(ResourceMetricTracker.class); private final ComparisonOperator _comparator; private final Float _violatingMetricValue; private final boolean _isNotReportingOffending; private final LinkedList _chronOrderedValues; /** * Creates an instance. * * @param comparator The comparator used to check for violating the trigger * condition. * @param violatingMetricValue The violating metric value. * @param isNotReportingOffending <code>true</code> if not reporting * resources are considered offending; * <code>false</code> otherwise. */ public ResourceMetricTracker(ComparisonOperator comparator, Float violatingMetricValue, boolean isNotReportingOffending) { _comparator = comparator; _violatingMetricValue = violatingMetricValue; _isNotReportingOffending = isNotReportingOffending; _chronOrderedValues = new LinkedList(); } /** * Track a new metric value. * * @param value The metric value. */ public void trackMetricValue(MetricValue value) { removeNewerTrackedMetrics(value); _chronOrderedValues.add(value); } /** * @return The current number of tracked metrics. */ public int getNumberOfTrackedMetrics() { return _chronOrderedValues.size(); } /** * Search for the first metric value violating the trigger condition in * the given time window. Any metric value older than the window start * time will be removed from tracking automatically. * * @param startTime The start timestamp for the window (inclusive). * @param endTime The end timestamp for the window (inclusive). * @return The violating metric value or <code>null</code> if no metric * violated in the time window. {@link MetricValue#NONE} is returned * if not reporting resources are considered offending and there * is no metric value in the time window. */ public MetricValue searchForViolatingMetricInWindow(long startTime, long endTime) { boolean debug = _log.isDebugEnabled(); boolean hasReportedInWindow = false; for (Iterator iter = _chronOrderedValues.iterator(); iter.hasNext();) { MetricValue metric = (MetricValue) iter.next(); long metricTimestamp = metric.getTimestamp(); if (metricTimestamp < startTime) { if (debug) { _log.debug("Aging out metrics older than the current " + "window start time: metric timestamp=" + metricTimestamp + ", start time=" + startTime); } iter.remove(); } else if (metric.getTimestamp() <= endTime) { hasReportedInWindow = true; if (_comparator.isTrue(new Float(metric.getValue()), _violatingMetricValue)) { return metric; } } // else The metric value is in the future - evaluate later } if (_isNotReportingOffending && !hasReportedInWindow) { return MetricValue.NONE; } else { // no violating metrics were found in the window return null; } } /** * If there are any newer (or with the same timestamp) tracked metrics than * this one that just came in, remove those newer tracked metrics. This * accounts for the backfilled case where the backfilled metrics reported * one value, but then the agent starts reporting again with the "real" * values that should preempt the backfilled values. * * @param value The metric value that just came in. */ private void removeNewerTrackedMetrics(MetricValue value) { if (_chronOrderedValues.isEmpty()) { return; } if (value.getTimestamp() <= ((MetricValue) _chronOrderedValues.getLast()).getTimestamp()) { _log.debug("Removing tracked metrics newer than timestamp=" + value.getTimestamp()); ListIterator iter = _chronOrderedValues.listIterator(_chronOrderedValues.size()); while (iter.hasPrevious()) { MetricValue trackedValue = (MetricValue) iter.previous(); if (trackedValue.getTimestamp() >= value.getTimestamp()) { iter.remove(); } else { return; } } } } }