/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License, version 2, as * published by the Free Software Foundation, and/or the GNU Lesser * General Public License, version 2.1, also 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 and the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU General Public License * and the GNU Lesser General Public License along with this program; * if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.rhq.core.domain.resource.composite; import java.io.Serializable; import java.util.Date; import java.util.List; import org.rhq.core.domain.measurement.Availability; import org.rhq.core.domain.measurement.AvailabilityType; /** * Summary information about a resource's availability history * * @author Greg Hinkle * @author John Mazzitelli */ public class ResourceAvailabilitySummary implements Serializable { private static final long serialVersionUID = 1L; private long now; // set to the current time when this object was created private long upTime; private long downTime; private long disabledTime; private long unknownTime; private int failures; private int disabled; private long lastChange; private AvailabilityType current; public ResourceAvailabilitySummary(List<Availability> availabilities) { this.now = System.currentTimeMillis(); long upTime = 0; long downTime = 0; long disabledTime = 0; long unknownTime = 0; int failures = 0; int disabled = 0; long lastChange = 0; AvailabilityType current = AvailabilityType.UNKNOWN; for (Availability avail : availabilities) { switch (avail.getAvailabilityType()) { case UP: { upTime += getStartEndTimeDuration(avail); break; } case DOWN: { downTime += getStartEndTimeDuration(avail); failures++; break; } case DISABLED: { disabledTime += getStartEndTimeDuration(avail); disabled++; break; } case UNKNOWN: { // ignore the initial unknown range that occurs prior to a resource being in inventory if (avail.getStartTime() > 0L) { unknownTime += getStartEndTimeDuration(avail); } break; } default: // Only stored avail types are relevant, MISSING, for example, is never stored break; } if (avail.getEndTime() == null) { lastChange = avail.getStartTime().longValue(); current = avail.getAvailabilityType(); } } this.upTime = upTime; this.downTime = downTime; this.disabledTime = disabledTime; this.unknownTime = unknownTime; this.failures = failures; this.disabled = disabled; this.lastChange = lastChange; this.current = current; } public ResourceAvailabilitySummary(long now, long upTime, long downTime, long disabledTime, long unknownTime, int failures, int disabled, long lastChange, AvailabilityType current) { this.now = now; this.upTime = upTime; this.downTime = downTime; this.disabledTime = disabledTime; this.unknownTime = unknownTime; this.failures = failures; this.disabled = disabled; this.lastChange = lastChange; this.current = current; } protected ResourceAvailabilitySummary() { // required for GWT } /** * Returns the mean-time-between-failures metric. The computation only takes into * account the uptimes and downtimes. Any time periods of UNKNOWN or DISABLED * availability are ignored. * * If there has been no failures yet, or there has only been one failure, the * MTBF cannot be calculated - in this case, 0 is returned. * * @return MTBF value in milliseconds */ public long getMTBF() { if (failures <= 1) { return 0; } // if our current state is UP, don't count the current up period in the calculations if (this.current == AvailabilityType.UP) { return (upTime - (this.now - this.lastChange)) / (failures - 1); } else { return upTime / (failures - 1); } } /** * Returns the mean-time-to-repair metric. The computation only takes into * account the uptimes and downtimes. Any time periods of UNKNOWN or DISABLED * availability are ignored. * * If there has been no failures yet, the MTTR cannot be calculated - in this case, 0 is returned. * * @return MTTR value in milliseconds */ public long getMTTR() { if (failures <= 0) { return 0; } // if our current state is DOWN, don't count the current down period in the calculations // since we don't have a subsequent UP and thus don't know the length of time it will be down before repair. if (this.current == AvailabilityType.DOWN) { return (failures > 1) ? (downTime - (this.now - this.lastChange)) / (failures - 1) : 0; } else { return downTime / failures; } } /** * Returns the percentage of time the availability has been UP. * For the purposes of this calculation, a DISABLED time period * explicitly counts as a "non-UP" time period. * This ignores any time periods of UNKNOWN availability. * * @return uptime percentage */ public double getUpPercentage() { long totalTime = upTime + downTime + disabledTime; return totalTime != 0 ? (((double) upTime) / totalTime) : 0; } /** * Returns the time the availability has been UP in milliseconds. * For the purposes of this calculation, only the times that UP * was the explicit state are used (that is, DOWN, DISABLED and UNKNOWN * time periods are excluded from the returned cumulative uptime). * * @return cumulative uptime in milliseconds */ public long getUpTime() { return upTime; } /** * Returns the percentage of time the availability has been DOWN. * For the purposes of this calculation, a DISABLED time period * is not considered DOWN. * This ignores any time periods of UNKNOWN availability. * * @return downtime percentage */ public double getDownPercentage() { long totalTime = upTime + downTime + disabledTime; return totalTime != 0 ? (((double) downTime) / totalTime) : 0; } /** * Returns the time the availability has been DOWN in milliseconds. * For the purposes of this calculation, only the times that DOWN * was the explicit state are used (that is, UP, DISABLED and UNKNOWN * time periods are excluded from the returned cumulative downtime). * * @return cumulative downtime in milliseconds */ public long getDownTime() { return downTime; } /** * Returns the percentage of time the availability has been DISABLED. * This ignores any time periods of UNKNOWN availability. * * @return percentage of time availability was disabled */ public double getDisabledPercentage() { long totalTime = upTime + downTime + disabledTime; return totalTime != 0 ? (((double) disabledTime) / totalTime) : 0; } /** * Returns the time the availability has been DISABLED in milliseconds. * * @return cumulative time in disabled state, in milliseconds */ public long getDisabledTime() { return disabledTime; } /** * Returns the time the availability has been UNKNOWN in milliseconds. * * @return cumulative time the availability was unknown, in milliseconds */ public long getUnknownTime() { return unknownTime; } /** * Returns the time the availability was in a known state * (which includes UP, DOWN and DISABLED). This obviously does not include * the times which the availability was in the UNKNOWN state. * * @return cumulative time the availability was known, in milliseconds */ public long getKnownTime() { return upTime + downTime + disabledTime; } /** * Returns the number of discrete times the availability went DOWN, which is * considered a failure. * * @return count of the number of failures */ public int getFailures() { return failures; } /** * Returns the number of discrete times the availability flipped to DISABLED. * * @return count of the number of times availability was disabled */ public int getDisabled() { return disabled; } public Date getLastChange() { return new Date(lastChange); } public AvailabilityType getCurrent() { return current; } /** * Returns the "current time" which is actually the time that was current at the time * when this object was created. * * @return the "current time" when this object was created */ public long getCurrentTime() { return now; } private long getStartEndTimeDuration(Availability avail) { long endTime = (avail.getEndTime() != null ? avail.getEndTime().longValue() : this.now); return endTime - avail.getStartTime().longValue(); } }