17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate * 267c478bd9Sstevel@tonic-gate * ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate package com.sun.solaris.domain.pools; 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate import java.math.BigInteger; 327c478bd9Sstevel@tonic-gate import java.util.HashMap; 337c478bd9Sstevel@tonic-gate import java.util.LinkedList; 347c478bd9Sstevel@tonic-gate import java.util.List; 357c478bd9Sstevel@tonic-gate import java.util.Iterator; 367c478bd9Sstevel@tonic-gate import com.sun.solaris.service.pools.Component; 377c478bd9Sstevel@tonic-gate import com.sun.solaris.service.pools.Resource; 387c478bd9Sstevel@tonic-gate import com.sun.solaris.service.pools.PoolsException; 397c478bd9Sstevel@tonic-gate import com.sun.solaris.service.pools.UnsignedInt64; 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate /** 427c478bd9Sstevel@tonic-gate * This represents a monitored resource and the techniques used to 437c478bd9Sstevel@tonic-gate * monitor the resource. 447c478bd9Sstevel@tonic-gate */ 457c478bd9Sstevel@tonic-gate class ResourceMonitor extends HashMap 467c478bd9Sstevel@tonic-gate { 477c478bd9Sstevel@tonic-gate /** 487c478bd9Sstevel@tonic-gate * The monitored resource. 497c478bd9Sstevel@tonic-gate */ 507c478bd9Sstevel@tonic-gate private Resource target; 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /** 537c478bd9Sstevel@tonic-gate * The size of the statistic buffer. 547c478bd9Sstevel@tonic-gate */ 557c478bd9Sstevel@tonic-gate private final int maxSize; 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /** 587c478bd9Sstevel@tonic-gate * Cached list of components to be monitored. 597c478bd9Sstevel@tonic-gate */ 607c478bd9Sstevel@tonic-gate private LinkedList compList; 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate /** 637c478bd9Sstevel@tonic-gate * Constructor. No monitor target and a default buffer size of 647c478bd9Sstevel@tonic-gate * 50. 657c478bd9Sstevel@tonic-gate */ ResourceMonitor()667c478bd9Sstevel@tonic-gate public ResourceMonitor() 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate this(null, 50); 697c478bd9Sstevel@tonic-gate } 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate /** 727c478bd9Sstevel@tonic-gate * Constructor. 737c478bd9Sstevel@tonic-gate * 747c478bd9Sstevel@tonic-gate * @param target The resource to be monitored. 757c478bd9Sstevel@tonic-gate * @param maxSize The maximum number of samples to be held. 767c478bd9Sstevel@tonic-gate */ ResourceMonitor(Resource target, int maxSize)777c478bd9Sstevel@tonic-gate public ResourceMonitor(Resource target, int maxSize) 787c478bd9Sstevel@tonic-gate { 797c478bd9Sstevel@tonic-gate super(); 807c478bd9Sstevel@tonic-gate this.target = target; 817c478bd9Sstevel@tonic-gate this.maxSize = maxSize; 827c478bd9Sstevel@tonic-gate compList = new LinkedList(); 83*55fea89dSDan Cross 847c478bd9Sstevel@tonic-gate } 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate /** 877c478bd9Sstevel@tonic-gate * Initialize the resource monitor with it's list of 887c478bd9Sstevel@tonic-gate * components. Components which are off-line or powered-off 897c478bd9Sstevel@tonic-gate * cannot be monitored, so they should be removed from the 907c478bd9Sstevel@tonic-gate * list of components. 917c478bd9Sstevel@tonic-gate * 927c478bd9Sstevel@tonic-gate * @throws PoolsException if there is an error accessing the 937c478bd9Sstevel@tonic-gate * pool elements. 947c478bd9Sstevel@tonic-gate */ initialize()957c478bd9Sstevel@tonic-gate public void initialize() throws PoolsException 967c478bd9Sstevel@tonic-gate { 977c478bd9Sstevel@tonic-gate compList.clear(); 987c478bd9Sstevel@tonic-gate List candidates = target.getComponents(null); 997c478bd9Sstevel@tonic-gate Iterator candIt = candidates.iterator(); 1007c478bd9Sstevel@tonic-gate while (candIt.hasNext()) { 1017c478bd9Sstevel@tonic-gate Component comp = (Component) candIt.next(); 1027c478bd9Sstevel@tonic-gate String status = comp.getStringProperty("cpu.status"); 1037c478bd9Sstevel@tonic-gate if (status.compareTo("off-line") != 0 && 1047c478bd9Sstevel@tonic-gate status.compareTo("powered-off") != 0) 1057c478bd9Sstevel@tonic-gate compList.add(comp); 1067c478bd9Sstevel@tonic-gate } 1077c478bd9Sstevel@tonic-gate } 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /** 1107c478bd9Sstevel@tonic-gate * Get the list of components which are actively monitored by 1117c478bd9Sstevel@tonic-gate * this resource. 1127c478bd9Sstevel@tonic-gate */ getComponents()1137c478bd9Sstevel@tonic-gate public List getComponents() 1147c478bd9Sstevel@tonic-gate { 1157c478bd9Sstevel@tonic-gate return ((List) compList.clone()); 1167c478bd9Sstevel@tonic-gate } 117*55fea89dSDan Cross 1187c478bd9Sstevel@tonic-gate /** 1197c478bd9Sstevel@tonic-gate * Return the maximum number of samples this monitor will 1207c478bd9Sstevel@tonic-gate * hold. 1217c478bd9Sstevel@tonic-gate */ getMaxSampleSize()1227c478bd9Sstevel@tonic-gate public int getMaxSampleSize() 1237c478bd9Sstevel@tonic-gate { 1247c478bd9Sstevel@tonic-gate return (maxSize); 1257c478bd9Sstevel@tonic-gate } 126*55fea89dSDan Cross 1277c478bd9Sstevel@tonic-gate /** 1287c478bd9Sstevel@tonic-gate * Return the object which is being monitored. 1297c478bd9Sstevel@tonic-gate */ getMonitored()1307c478bd9Sstevel@tonic-gate public Resource getMonitored() 1317c478bd9Sstevel@tonic-gate { 1327c478bd9Sstevel@tonic-gate return (target); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate /** 1367c478bd9Sstevel@tonic-gate * Set the resource to be monitored. A resource target can 1377c478bd9Sstevel@tonic-gate * only be set once, if you attempt to modify it then an 1387c478bd9Sstevel@tonic-gate * IllegalArgumentException is thrown. 1397c478bd9Sstevel@tonic-gate * 1407c478bd9Sstevel@tonic-gate * @param target The resource to be monitored. 1417c478bd9Sstevel@tonic-gate * @throws IllegalArgumentException if the target has already 1427c478bd9Sstevel@tonic-gate * been set. 1437c478bd9Sstevel@tonic-gate */ setResource(Resource target)1447c478bd9Sstevel@tonic-gate public void setResource(Resource target) 1457c478bd9Sstevel@tonic-gate { 1467c478bd9Sstevel@tonic-gate if (this.target != null) 1477c478bd9Sstevel@tonic-gate this.target = target; 1487c478bd9Sstevel@tonic-gate else 1497c478bd9Sstevel@tonic-gate throw new IllegalArgumentException("Once the target " + 1507c478bd9Sstevel@tonic-gate "of a ResourceMonitor is set, it cannot be " + 1517c478bd9Sstevel@tonic-gate "changed."); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate /** 1557c478bd9Sstevel@tonic-gate * Return the name of the monitored object. 1567c478bd9Sstevel@tonic-gate * 1577c478bd9Sstevel@tonic-gate * @throws PoolsException if there is an error accessing the 1587c478bd9Sstevel@tonic-gate * pool element. 1597c478bd9Sstevel@tonic-gate */ getName()1607c478bd9Sstevel@tonic-gate public String getName() throws PoolsException 1617c478bd9Sstevel@tonic-gate { 1627c478bd9Sstevel@tonic-gate String type = target.getStringProperty("type"); 1637c478bd9Sstevel@tonic-gate return (target.getStringProperty(type + ".name")); 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /** 1677c478bd9Sstevel@tonic-gate * Update the derived statistics. 1687c478bd9Sstevel@tonic-gate */ updateDerived()1697c478bd9Sstevel@tonic-gate public void updateDerived() 1707c478bd9Sstevel@tonic-gate { 1717c478bd9Sstevel@tonic-gate StatisticList util = (StatisticList) get("utilization"); 1727c478bd9Sstevel@tonic-gate AggregateStatistic stat = calcDerivedStatistic("utilization"); 1737c478bd9Sstevel@tonic-gate if (stat != null) 1747c478bd9Sstevel@tonic-gate util.add(stat); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate /** 1787c478bd9Sstevel@tonic-gate * Get a derived statistic. 1797c478bd9Sstevel@tonic-gate * 1807c478bd9Sstevel@tonic-gate * @param name The name of the statistic to get. 1817c478bd9Sstevel@tonic-gate */ getDerivedStatistic(String name)1827c478bd9Sstevel@tonic-gate public AggregateStatistic getDerivedStatistic(String name) 1837c478bd9Sstevel@tonic-gate { 1847c478bd9Sstevel@tonic-gate return ((AggregateStatistic)((StatisticList)get(name)). 1857c478bd9Sstevel@tonic-gate getLast()); 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate /** 1897c478bd9Sstevel@tonic-gate * Return the latest value of a derived statistic. 1907c478bd9Sstevel@tonic-gate * 1917c478bd9Sstevel@tonic-gate * @param name is the name of the derived statistic to be 1927c478bd9Sstevel@tonic-gate * returned. 1937c478bd9Sstevel@tonic-gate */ calcDerivedStatistic(String name)1947c478bd9Sstevel@tonic-gate private AggregateStatistic calcDerivedStatistic(String name) 1957c478bd9Sstevel@tonic-gate { 1967c478bd9Sstevel@tonic-gate /* 1977c478bd9Sstevel@tonic-gate * The only statistic which can be obtained from this 1987c478bd9Sstevel@tonic-gate * resource monitor is utilization. A utilization 1997c478bd9Sstevel@tonic-gate * statistic actually represents a complex 2007c478bd9Sstevel@tonic-gate * manipulation of several lower level 2017c478bd9Sstevel@tonic-gate * statistics. This manipulation is performed here 2027c478bd9Sstevel@tonic-gate * until a good interface can be thought through which 2037c478bd9Sstevel@tonic-gate * best captures this abstraction. 2047c478bd9Sstevel@tonic-gate */ 2057c478bd9Sstevel@tonic-gate if (name.compareTo("utilization") != 0) 2067c478bd9Sstevel@tonic-gate throw new IllegalArgumentException("No such derived " 2077c478bd9Sstevel@tonic-gate + "statistic: " + name); 2087c478bd9Sstevel@tonic-gate /* 2097c478bd9Sstevel@tonic-gate * This statistic is based on lower level 2107c478bd9Sstevel@tonic-gate * monotonically increasing numbers. The statistic can 2117c478bd9Sstevel@tonic-gate * thus only be derived as an observation of the 2127c478bd9Sstevel@tonic-gate * change in value over time of these values. 2137c478bd9Sstevel@tonic-gate */ 214*55fea89dSDan Cross 2157c478bd9Sstevel@tonic-gate StatisticList first = (StatisticList) get("idle"); 216*55fea89dSDan Cross 2177c478bd9Sstevel@tonic-gate switch (first.size()) { 2187c478bd9Sstevel@tonic-gate case 0: 2197c478bd9Sstevel@tonic-gate case 1: 2207c478bd9Sstevel@tonic-gate return (null); 2217c478bd9Sstevel@tonic-gate default: 2227c478bd9Sstevel@tonic-gate BigInteger total = new BigInteger("0"); 2237c478bd9Sstevel@tonic-gate double utilV = 0.0; 2247c478bd9Sstevel@tonic-gate double idleV = 0.0; 2257c478bd9Sstevel@tonic-gate LinkedList keys = new LinkedList(keySet()); 2267c478bd9Sstevel@tonic-gate keys.remove("utilization"); 2277c478bd9Sstevel@tonic-gate for (int i = 0; i < keys.size(); i++) { 2287c478bd9Sstevel@tonic-gate StatisticList sl = (StatisticList) get(keys. 2297c478bd9Sstevel@tonic-gate get(i)); 2307c478bd9Sstevel@tonic-gate AggregateStatistic sv1 = (AggregateStatistic) 2317c478bd9Sstevel@tonic-gate sl.getLast(); 2327c478bd9Sstevel@tonic-gate AggregateStatistic sv2 = (AggregateStatistic) 2337c478bd9Sstevel@tonic-gate sl.get(sl.size() - 2); 2347c478bd9Sstevel@tonic-gate if (sl.getName().compareTo("idle") == 0) 2357c478bd9Sstevel@tonic-gate idleV = ((UnsignedInt64) sv1. 2367c478bd9Sstevel@tonic-gate subtract(sv2).getValue()). 2377c478bd9Sstevel@tonic-gate doubleValue(); 2387c478bd9Sstevel@tonic-gate total = total.add((UnsignedInt64) sv1. 2397c478bd9Sstevel@tonic-gate subtract(sv2).getValue()); 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate utilV = 100 * ((total.doubleValue() - idleV) / 2427c478bd9Sstevel@tonic-gate total.doubleValue()); 2437c478bd9Sstevel@tonic-gate return (new DoubleStatistic(new Double(utilV), 2447c478bd9Sstevel@tonic-gate ((AggregateStatistic)first.get(first.size() - 2457c478bd9Sstevel@tonic-gate 2)).getStart(), ((AggregateStatistic)first. 2467c478bd9Sstevel@tonic-gate getLast()).getEnd())); 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate } 2497c478bd9Sstevel@tonic-gate resetData(String name)2507c478bd9Sstevel@tonic-gate void resetData(String name) 2517c478bd9Sstevel@tonic-gate { 2527c478bd9Sstevel@tonic-gate StatisticList sl = (StatisticList) get(name); 2537c478bd9Sstevel@tonic-gate sl.clear(); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate } 256