package com.sun.solaris.domain.pools;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.*;
import java.util.logging.*;
import com.sun.solaris.service.kstat.*;
import com.sun.solaris.service.logging.Severity;
import com.sun.solaris.domain.pools.*;
import com.sun.solaris.service.pools.*;
import com.sun.solaris.service.timer.*;
class SystemMonitor implements Monitor
{
private Configuration conf;
private Map monitored;
public static final int DEF_SAMPLE_INT = 15000;
private int interval;
static final String SAMPLE_INTERVAL_PROP_NAME =
"system.poold.monitor-interval";
private KstatCtl kc;
private final String stats[] = { "idle", "kernel", "wait", "user" };
private RecurringEventTimer timer;
private int sampleCount = 0;
private Date lastSampleTime = null;
public SystemMonitor()
{
this(null);
}
public SystemMonitor(Configuration conf)
{
this.conf = conf;
monitored = new HashMap();
kc = new KstatCtl();
}
public void initialize(Configuration conf) throws PoolsException,
StaleMonitorException
{
Poold.CONF_LOG.log(Severity.DEBUG, "initializing");
this.conf = conf;
try {
kc.chainUpdate();
} catch (KstatChainUpdateException kcue) {
Poold.utility.die(Poold.CONF_LOG, kcue);
}
try {
interval = (int)conf.getLongProperty(
SAMPLE_INTERVAL_PROP_NAME);
} catch (PoolsException pe) {
interval = DEF_SAMPLE_INT;
}
timer = new SimpleRecurringEventTimer(interval);
setResourceMonitors("pset");
}
private void setResourceMonitors(String type) throws PoolsException,
StaleMonitorException
{
Value val = new Value("type", type);
List valueList = new LinkedList();
valueList.add(val);
Iterator resIt = conf.getResources(valueList).iterator();
val.close();
HashSet oldKeys = new HashSet(monitored.keySet());
while (resIt.hasNext()) {
Resource res = (Resource)resIt.next();
ResourceMonitor mon = null;
boolean activeComponents = false;
List compList = res.getComponents(null);
Iterator compIt = compList.iterator();
while (compIt.hasNext()) {
Component comp = (Component) compIt.next();
String status = comp.getStringProperty(
"cpu.status");
if (status.compareTo("off-line") != 0 &&
status.compareTo("powered-off") != 0) {
activeComponents = true;
break;
}
}
if (activeComponents == false)
continue;
if (monitored.containsKey(res)) {
mon = get(res);
for (int i = 0; i < stats.length; i++)
mon.resetData(stats[i]);
} else {
mon = new ResourceMonitor(res, 50);
for (int i = 0; i < stats.length; i++) {
StatisticList sl = new StatisticList(
stats[i], 2);
mon.put(stats[i], sl);
}
mon.put("utilization", new StatisticList(
"utilization", mon.getMaxSampleSize(),
true));
monitored.put(res, mon);
}
mon.initialize();
oldKeys.remove(res);
}
monitored.keySet().removeAll(oldKeys);
}
public void getNext() throws StaleMonitorException, PoolsException,
InterruptedException
{
Poold.MON_LOG.log(Severity.DEBUG, "waiting sampling interval");
Date start = lastSampleTime;
if (start == null)
start = new Date();
timer.waitUntilNextFiring();
Date end = new Date();
Poold.MON_LOG.log(Severity.DEBUG, "sampling");
Iterator itMon = monitored.values().iterator();
while (itMon.hasNext()) {
ResourceMonitor mon = (ResourceMonitor) itMon.next();
List compList = mon.getComponents();
Iterator itComp = compList.iterator();
BigInteger statsv[] = new BigInteger[4];
while (itComp.hasNext()) {
Component cpu = (Component) itComp.next();
Kstat kstat = kc.lookup("cpu",
(int) cpu.getLongProperty("cpu.sys_id"),
"sys");
if (kstat == null)
throw new StaleMonitorException();
UnsignedInt64 value;
try {
kstat.read();
for (int i = 0; i < stats.length; i++) {
value = (UnsignedInt64) kstat.
getValue("cpu_ticks_" +
stats[i]);
if (value == null)
throw new
StaleMonitorException();
if (statsv[i] == null)
statsv[i] = value;
else
statsv[i] = statsv[i].
add(value);
}
} catch (KstatException ke) {
StaleMonitorException sme =
new StaleMonitorException();
sme.initCause(ke);
Poold.MON_LOG.log(Severity.DEBUG,
"configuration necessary due to "
+ ke);
throw(sme);
}
}
if (compList.isEmpty() == false) {
for (int i = 0; i < stats.length; i++) {
StatisticList sl;
sl = (StatisticList) mon.get(stats[i]);
sl.add(new UnsignedInt64Statistic(
new UnsignedInt64(statsv[i].
divide(new BigInteger(
Integer.toString(
compList.size())))),
start, end));
}
}
mon.updateDerived();
}
sampleCount++;
lastSampleTime = end;
}
public int getSampleCount()
{
return (sampleCount);
}
public double getUtilization(Resource res) throws StaleMonitorException
{
ResourceMonitor mon = get(res);
DoubleStatistic util = null;
try {
util = (DoubleStatistic)mon.getDerivedStatistic(
"utilization");
} catch (NoSuchElementException nsee) {
util = new DoubleStatistic(Double.valueOf(0));
}
Poold.MON_LOG.log(Severity.DEBUG,
res + " utilization " + util.toString());
return (((Double)util.getValue()).doubleValue());
}
public boolean isValid()
{
Iterator itMon = monitored.values().iterator();
while (itMon.hasNext()) {
ResourceMonitor mon = (ResourceMonitor) itMon.next();
Iterator itSL = mon.values().iterator();
while (itSL.hasNext()) {
StatisticList sl = (StatisticList) itSL.next();
if (sl.getName().compareTo("utilization") ==
0) {
if (sl.isValid() == false)
return (false);
}
}
}
return (true);
}
public ResourceMonitor get(Resource res) throws StaleMonitorException
{
ResourceMonitor rm = (ResourceMonitor)monitored.get(res);
if (rm == null)
throw new StaleMonitorException();
return (rm);
}
}