xref: /illumos-gate/usr/src/cmd/pools/poold/com/sun/solaris/domain/pools/ResourceMonitor.java (revision 55fea89dcaa64928bed4327112404dcb3e07b79f)
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