1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate * 26*7c478bd9Sstevel@tonic-gate * ident "%Z%%M% %I% %E% SMI" 27*7c478bd9Sstevel@tonic-gate */ 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate package com.sun.solaris.domain.pools; 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate import java.math.BigInteger; 32*7c478bd9Sstevel@tonic-gate import java.util.HashMap; 33*7c478bd9Sstevel@tonic-gate import java.util.LinkedList; 34*7c478bd9Sstevel@tonic-gate import java.util.List; 35*7c478bd9Sstevel@tonic-gate import java.util.Iterator; 36*7c478bd9Sstevel@tonic-gate import com.sun.solaris.service.pools.Component; 37*7c478bd9Sstevel@tonic-gate import com.sun.solaris.service.pools.Resource; 38*7c478bd9Sstevel@tonic-gate import com.sun.solaris.service.pools.PoolsException; 39*7c478bd9Sstevel@tonic-gate import com.sun.solaris.service.pools.UnsignedInt64; 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /** 42*7c478bd9Sstevel@tonic-gate * This represents a monitored resource and the techniques used to 43*7c478bd9Sstevel@tonic-gate * monitor the resource. 44*7c478bd9Sstevel@tonic-gate */ 45*7c478bd9Sstevel@tonic-gate class ResourceMonitor extends HashMap 46*7c478bd9Sstevel@tonic-gate { 47*7c478bd9Sstevel@tonic-gate /** 48*7c478bd9Sstevel@tonic-gate * The monitored resource. 49*7c478bd9Sstevel@tonic-gate */ 50*7c478bd9Sstevel@tonic-gate private Resource target; 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate /** 53*7c478bd9Sstevel@tonic-gate * The size of the statistic buffer. 54*7c478bd9Sstevel@tonic-gate */ 55*7c478bd9Sstevel@tonic-gate private final int maxSize; 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate /** 58*7c478bd9Sstevel@tonic-gate * Cached list of components to be monitored. 59*7c478bd9Sstevel@tonic-gate */ 60*7c478bd9Sstevel@tonic-gate private LinkedList compList; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate /** 63*7c478bd9Sstevel@tonic-gate * Constructor. No monitor target and a default buffer size of 64*7c478bd9Sstevel@tonic-gate * 50. 65*7c478bd9Sstevel@tonic-gate */ ResourceMonitor()66*7c478bd9Sstevel@tonic-gate public ResourceMonitor() 67*7c478bd9Sstevel@tonic-gate { 68*7c478bd9Sstevel@tonic-gate this(null, 50); 69*7c478bd9Sstevel@tonic-gate } 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate /** 72*7c478bd9Sstevel@tonic-gate * Constructor. 73*7c478bd9Sstevel@tonic-gate * 74*7c478bd9Sstevel@tonic-gate * @param target The resource to be monitored. 75*7c478bd9Sstevel@tonic-gate * @param maxSize The maximum number of samples to be held. 76*7c478bd9Sstevel@tonic-gate */ ResourceMonitor(Resource target, int maxSize)77*7c478bd9Sstevel@tonic-gate public ResourceMonitor(Resource target, int maxSize) 78*7c478bd9Sstevel@tonic-gate { 79*7c478bd9Sstevel@tonic-gate super(); 80*7c478bd9Sstevel@tonic-gate this.target = target; 81*7c478bd9Sstevel@tonic-gate this.maxSize = maxSize; 82*7c478bd9Sstevel@tonic-gate compList = new LinkedList(); 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate /** 87*7c478bd9Sstevel@tonic-gate * Initialize the resource monitor with it's list of 88*7c478bd9Sstevel@tonic-gate * components. Components which are off-line or powered-off 89*7c478bd9Sstevel@tonic-gate * cannot be monitored, so they should be removed from the 90*7c478bd9Sstevel@tonic-gate * list of components. 91*7c478bd9Sstevel@tonic-gate * 92*7c478bd9Sstevel@tonic-gate * @throws PoolsException if there is an error accessing the 93*7c478bd9Sstevel@tonic-gate * pool elements. 94*7c478bd9Sstevel@tonic-gate */ initialize()95*7c478bd9Sstevel@tonic-gate public void initialize() throws PoolsException 96*7c478bd9Sstevel@tonic-gate { 97*7c478bd9Sstevel@tonic-gate compList.clear(); 98*7c478bd9Sstevel@tonic-gate List candidates = target.getComponents(null); 99*7c478bd9Sstevel@tonic-gate Iterator candIt = candidates.iterator(); 100*7c478bd9Sstevel@tonic-gate while (candIt.hasNext()) { 101*7c478bd9Sstevel@tonic-gate Component comp = (Component) candIt.next(); 102*7c478bd9Sstevel@tonic-gate String status = comp.getStringProperty("cpu.status"); 103*7c478bd9Sstevel@tonic-gate if (status.compareTo("off-line") != 0 && 104*7c478bd9Sstevel@tonic-gate status.compareTo("powered-off") != 0) 105*7c478bd9Sstevel@tonic-gate compList.add(comp); 106*7c478bd9Sstevel@tonic-gate } 107*7c478bd9Sstevel@tonic-gate } 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /** 110*7c478bd9Sstevel@tonic-gate * Get the list of components which are actively monitored by 111*7c478bd9Sstevel@tonic-gate * this resource. 112*7c478bd9Sstevel@tonic-gate */ getComponents()113*7c478bd9Sstevel@tonic-gate public List getComponents() 114*7c478bd9Sstevel@tonic-gate { 115*7c478bd9Sstevel@tonic-gate return ((List) compList.clone()); 116*7c478bd9Sstevel@tonic-gate } 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate /** 119*7c478bd9Sstevel@tonic-gate * Return the maximum number of samples this monitor will 120*7c478bd9Sstevel@tonic-gate * hold. 121*7c478bd9Sstevel@tonic-gate */ getMaxSampleSize()122*7c478bd9Sstevel@tonic-gate public int getMaxSampleSize() 123*7c478bd9Sstevel@tonic-gate { 124*7c478bd9Sstevel@tonic-gate return (maxSize); 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate /** 128*7c478bd9Sstevel@tonic-gate * Return the object which is being monitored. 129*7c478bd9Sstevel@tonic-gate */ getMonitored()130*7c478bd9Sstevel@tonic-gate public Resource getMonitored() 131*7c478bd9Sstevel@tonic-gate { 132*7c478bd9Sstevel@tonic-gate return (target); 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate /** 136*7c478bd9Sstevel@tonic-gate * Set the resource to be monitored. A resource target can 137*7c478bd9Sstevel@tonic-gate * only be set once, if you attempt to modify it then an 138*7c478bd9Sstevel@tonic-gate * IllegalArgumentException is thrown. 139*7c478bd9Sstevel@tonic-gate * 140*7c478bd9Sstevel@tonic-gate * @param target The resource to be monitored. 141*7c478bd9Sstevel@tonic-gate * @throws IllegalArgumentException if the target has already 142*7c478bd9Sstevel@tonic-gate * been set. 143*7c478bd9Sstevel@tonic-gate */ setResource(Resource target)144*7c478bd9Sstevel@tonic-gate public void setResource(Resource target) 145*7c478bd9Sstevel@tonic-gate { 146*7c478bd9Sstevel@tonic-gate if (this.target != null) 147*7c478bd9Sstevel@tonic-gate this.target = target; 148*7c478bd9Sstevel@tonic-gate else 149*7c478bd9Sstevel@tonic-gate throw new IllegalArgumentException("Once the target " + 150*7c478bd9Sstevel@tonic-gate "of a ResourceMonitor is set, it cannot be " + 151*7c478bd9Sstevel@tonic-gate "changed."); 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate /** 155*7c478bd9Sstevel@tonic-gate * Return the name of the monitored object. 156*7c478bd9Sstevel@tonic-gate * 157*7c478bd9Sstevel@tonic-gate * @throws PoolsException if there is an error accessing the 158*7c478bd9Sstevel@tonic-gate * pool element. 159*7c478bd9Sstevel@tonic-gate */ getName()160*7c478bd9Sstevel@tonic-gate public String getName() throws PoolsException 161*7c478bd9Sstevel@tonic-gate { 162*7c478bd9Sstevel@tonic-gate String type = target.getStringProperty("type"); 163*7c478bd9Sstevel@tonic-gate return (target.getStringProperty(type + ".name")); 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /** 167*7c478bd9Sstevel@tonic-gate * Update the derived statistics. 168*7c478bd9Sstevel@tonic-gate */ updateDerived()169*7c478bd9Sstevel@tonic-gate public void updateDerived() 170*7c478bd9Sstevel@tonic-gate { 171*7c478bd9Sstevel@tonic-gate StatisticList util = (StatisticList) get("utilization"); 172*7c478bd9Sstevel@tonic-gate AggregateStatistic stat = calcDerivedStatistic("utilization"); 173*7c478bd9Sstevel@tonic-gate if (stat != null) 174*7c478bd9Sstevel@tonic-gate util.add(stat); 175*7c478bd9Sstevel@tonic-gate } 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate /** 178*7c478bd9Sstevel@tonic-gate * Get a derived statistic. 179*7c478bd9Sstevel@tonic-gate * 180*7c478bd9Sstevel@tonic-gate * @param name The name of the statistic to get. 181*7c478bd9Sstevel@tonic-gate */ getDerivedStatistic(String name)182*7c478bd9Sstevel@tonic-gate public AggregateStatistic getDerivedStatistic(String name) 183*7c478bd9Sstevel@tonic-gate { 184*7c478bd9Sstevel@tonic-gate return ((AggregateStatistic)((StatisticList)get(name)). 185*7c478bd9Sstevel@tonic-gate getLast()); 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate /** 189*7c478bd9Sstevel@tonic-gate * Return the latest value of a derived statistic. 190*7c478bd9Sstevel@tonic-gate * 191*7c478bd9Sstevel@tonic-gate * @param name is the name of the derived statistic to be 192*7c478bd9Sstevel@tonic-gate * returned. 193*7c478bd9Sstevel@tonic-gate */ calcDerivedStatistic(String name)194*7c478bd9Sstevel@tonic-gate private AggregateStatistic calcDerivedStatistic(String name) 195*7c478bd9Sstevel@tonic-gate { 196*7c478bd9Sstevel@tonic-gate /* 197*7c478bd9Sstevel@tonic-gate * The only statistic which can be obtained from this 198*7c478bd9Sstevel@tonic-gate * resource monitor is utilization. A utilization 199*7c478bd9Sstevel@tonic-gate * statistic actually represents a complex 200*7c478bd9Sstevel@tonic-gate * manipulation of several lower level 201*7c478bd9Sstevel@tonic-gate * statistics. This manipulation is performed here 202*7c478bd9Sstevel@tonic-gate * until a good interface can be thought through which 203*7c478bd9Sstevel@tonic-gate * best captures this abstraction. 204*7c478bd9Sstevel@tonic-gate */ 205*7c478bd9Sstevel@tonic-gate if (name.compareTo("utilization") != 0) 206*7c478bd9Sstevel@tonic-gate throw new IllegalArgumentException("No such derived " 207*7c478bd9Sstevel@tonic-gate + "statistic: " + name); 208*7c478bd9Sstevel@tonic-gate /* 209*7c478bd9Sstevel@tonic-gate * This statistic is based on lower level 210*7c478bd9Sstevel@tonic-gate * monotonically increasing numbers. The statistic can 211*7c478bd9Sstevel@tonic-gate * thus only be derived as an observation of the 212*7c478bd9Sstevel@tonic-gate * change in value over time of these values. 213*7c478bd9Sstevel@tonic-gate */ 214*7c478bd9Sstevel@tonic-gate 215*7c478bd9Sstevel@tonic-gate StatisticList first = (StatisticList) get("idle"); 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate switch (first.size()) { 218*7c478bd9Sstevel@tonic-gate case 0: 219*7c478bd9Sstevel@tonic-gate case 1: 220*7c478bd9Sstevel@tonic-gate return (null); 221*7c478bd9Sstevel@tonic-gate default: 222*7c478bd9Sstevel@tonic-gate BigInteger total = new BigInteger("0"); 223*7c478bd9Sstevel@tonic-gate double utilV = 0.0; 224*7c478bd9Sstevel@tonic-gate double idleV = 0.0; 225*7c478bd9Sstevel@tonic-gate LinkedList keys = new LinkedList(keySet()); 226*7c478bd9Sstevel@tonic-gate keys.remove("utilization"); 227*7c478bd9Sstevel@tonic-gate for (int i = 0; i < keys.size(); i++) { 228*7c478bd9Sstevel@tonic-gate StatisticList sl = (StatisticList) get(keys. 229*7c478bd9Sstevel@tonic-gate get(i)); 230*7c478bd9Sstevel@tonic-gate AggregateStatistic sv1 = (AggregateStatistic) 231*7c478bd9Sstevel@tonic-gate sl.getLast(); 232*7c478bd9Sstevel@tonic-gate AggregateStatistic sv2 = (AggregateStatistic) 233*7c478bd9Sstevel@tonic-gate sl.get(sl.size() - 2); 234*7c478bd9Sstevel@tonic-gate if (sl.getName().compareTo("idle") == 0) 235*7c478bd9Sstevel@tonic-gate idleV = ((UnsignedInt64) sv1. 236*7c478bd9Sstevel@tonic-gate subtract(sv2).getValue()). 237*7c478bd9Sstevel@tonic-gate doubleValue(); 238*7c478bd9Sstevel@tonic-gate total = total.add((UnsignedInt64) sv1. 239*7c478bd9Sstevel@tonic-gate subtract(sv2).getValue()); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate utilV = 100 * ((total.doubleValue() - idleV) / 242*7c478bd9Sstevel@tonic-gate total.doubleValue()); 243*7c478bd9Sstevel@tonic-gate return (new DoubleStatistic(new Double(utilV), 244*7c478bd9Sstevel@tonic-gate ((AggregateStatistic)first.get(first.size() - 245*7c478bd9Sstevel@tonic-gate 2)).getStart(), ((AggregateStatistic)first. 246*7c478bd9Sstevel@tonic-gate getLast()).getEnd())); 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate resetData(String name)250*7c478bd9Sstevel@tonic-gate void resetData(String name) 251*7c478bd9Sstevel@tonic-gate { 252*7c478bd9Sstevel@tonic-gate StatisticList sl = (StatisticList) get(name); 253*7c478bd9Sstevel@tonic-gate sl.clear(); 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate } 256