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