Mercurial > hg > blitz_condensed
view src/org/dancres/blitz/tools/CondensedStats.java @ 34:6f68e94c1fb8 default tip
Add CondensedStats monitoring utility, equivalent to vmstat
author | Dominic Cleal <dominic-cleal@cdo2.com> |
---|---|
date | Thu, 05 Aug 2010 11:07:25 +0100 |
parents | |
children |
line wrap: on
line source
package org.dancres.blitz.tools; import java.io.PrintStream; import java.rmi.RemoteException; import java.util.ArrayList; import java.util.Collection; import java.util.Formatter; import org.dancres.blitz.remote.StatsAdmin; import org.dancres.blitz.stats.BlockingOpsStat; import org.dancres.blitz.stats.EventQueueStat; import org.dancres.blitz.stats.IOStat; import org.dancres.blitz.stats.InstanceCount; import org.dancres.blitz.stats.MemoryStat; import org.dancres.blitz.stats.MissedOpsStat; import org.dancres.blitz.stats.OpStat; import org.dancres.blitz.stats.Stat; import org.dancres.blitz.stats.TaskQueueStat; import org.dancres.blitz.stats.ThreadStat; import org.dancres.blitz.stats.TxnStat; /** <p>CondensedStats accepts a spacename as an argument and a loop time. It then regularly prints a condensed view of some important space stats every loop time seconds. Specifying a loop time of 0 will cause MonitorStats to dump stats once and exit.</p> <p>Typical usage: <pre> java -Xmx256m -Djava.security.policy=config/policy.all -classpath /home/dan/jini/jini2_0/lib/jsk-platform.jar:/home/dan/src/jini/space/build:/home/dan/jini/jini2_0/lib/jini-ext.jar:/home/dan/jini/jini2_0/lib/sun-util.jar org.dancres.blitz.tools.CondensedStats dancres 20 </pre> @see org.dancres.blitz.remote.BlitzAdmin */ public class CondensedStats extends MonitorStats { public static void main(String args[]) { new CondensedStats().startup(args); } @Override Runnable getWatcher(StatsAdmin anAdmin, long aTimeout) { return new CondensedWatcher(anAdmin, aTimeout); } /** * Provides a vmstat-style one line repeating summary of Blitz statistics. * Includes operation counts, active txns/ops, listeners and queue stats, * writer I/O and VM stats. */ static class CondensedWatcher implements Runnable { private StatsAdmin theAdmin; private long theTimeout; private Stat[] theLastStats; CondensedWatcher(StatsAdmin anAdmin, long aTimeout) { theAdmin = anAdmin; theTimeout = aTimeout; } public void run() { boolean run = true; while (run) { try { // if timeout is 0, run once over a 1 second period if (theTimeout == 0) { run = false; theTimeout = 1000; } printHeader(System.out); theLastStats = theAdmin.getStats(); for (int i = 0;; i++) { Thread.sleep(theTimeout); print(System.out, (int)theTimeout / 1000); if ((i + 1) % 48 == 0) printHeader(System.out); } } catch (Exception anE) { System.err.println(anE); anE.printStackTrace(); } } } public void printHeader(PrintStream out) { out.println("-----ops---- " + " missed " + "obj " + "---active-- " + "listeners " + "---queues-- " + "------io----- " + "-----vm-----"); out.println(" r t w " + " r t " + "+/- " + "txn r t " + " tr pt " + "evt rem oth " + " i/o qsz thr " + "thrd mem max"); } public void print(PrintStream out, int interval) throws RemoteException { Stat[] last = theLastStats; Stat[] stats = theAdmin.getStats(); // Operation count since last iteration long opReads = getOpCount(stats, OpStat.READS) - getOpCount(last, OpStat.READS); long opTakes = getOpCount(stats, OpStat.TAKES) - getOpCount(last, OpStat.TAKES); long opWrites = (getOpCount(stats, OpStat.WRITES) - getOpCount(last, OpStat.WRITES)) / interval; // Missed operations, not available until first operation long missReads = 0, missTakes = 0; MissedOpsStat missedStat = getStatistic(stats, MissedOpsStat.class); MissedOpsStat missedLast = getStatistic(stats, MissedOpsStat.class); if (missedStat != null && missedLast != null) { missReads = (missedStat.getMissedReads() - missedLast.getMissedReads()) / interval; missTakes = (missedStat.getMissedTakes() - missedLast.getMissedTakes()) / interval; } // Change op counts to include misses opReads = (opReads + missReads) / interval; opTakes = (opTakes + missTakes) / interval; // Overall instance count long instances = (getInstanceCount(stats) - getInstanceCount(last)) / interval; // Active operations/txns int activeTxn = getStatistic(stats, TxnStat.class).getActiveTxnCount(); // Not available until after first space operation int activeRead = 0, activeTake = 0; BlockingOpsStat blockedOps = getStatistic(stats, BlockingOpsStat.class); if (blockedOps != null) { activeRead = blockedOps.getReaders(); activeTake = blockedOps.getTakers(); } // Notify listeners int listenTrans = getStatistic(stats, EventQueueStat.class).getTransientCount(); int listenPers = getStatistic(stats, EventQueueStat.class).getPersistentCount(); // Queues, internal notify queue, remote notify queue and other tasks int queueEvents = getTaskQueue(stats, "Events"); int queueRemote = getTaskQueue(stats, "RemoteEvent"); int queueOther = getTaskQueue(stats, "DefaultTask"); // Writer I/O if persistent storage model in use double ioRatio = 0; int ioQueueSize = 0, ioThrottle = 0; IOStat myIoStat = getStatistic(stats, IOStat.class); if (myIoStat != null) { ioRatio = myIoStat.getInOutRatio(); ioQueueSize = getStatistic(stats, IOStat.class).getQueueSize(); ioThrottle = (getStatistic(stats, IOStat.class).getThrottleCount() - getStatistic(last, IOStat.class).getThrottleCount()) / interval; } // Virtual machine int vmThreads = getStatistic(stats, ThreadStat.class).getThreadCount(); double vmMemory = getStatistic(stats, MemoryStat.class).getCurrentMemory(); vmMemory = vmMemory / 1024 / 1024 / 1024; double vmMaxMem = getStatistic(stats, MemoryStat.class).getMaxMemory(); vmMaxMem = vmMaxMem / 1024 / 1024 / 1024; // r t w$ r w$ +/-$txn r t$ tr pt String formatString = "%4d %3d %3d %4d %3d %5d %4d %3d %3d %5d %4d "; // evt rem oth$i/o qsz thr$thrd mem max formatString += "%4d %3d %3d %5.1f %4d %3d %5d %3.1f %3.1f"; String line = new Formatter().format(formatString, opReads, opTakes, opWrites, missReads, missTakes, instances, activeTxn, activeRead, activeTake, listenTrans, listenPers, queueEvents, queueRemote, queueOther, ioRatio, ioQueueSize, ioThrottle, vmThreads, vmMemory, vmMaxMem).toString(); out.println(line); theLastStats = stats; } private <T extends Stat> Collection<T> getStatistics(Stat[] allStats, Class<T> statClazz) { Collection<T> ret = new ArrayList<T>(); for (Stat stat : allStats) if (statClazz.isInstance(stat)) ret.add(statClazz.cast(stat)); return ret; } private <T extends Stat> T getStatistic(Stat[] allStats, Class<T> statClazz) { Collection<T> subset = getStatistics(allStats, statClazz); return (subset.isEmpty()) ? null : subset.iterator().next(); } /** Adds up operations across all entry types. * @param opType OpStat.TAKES/READS/WRITES */ private long getOpCount(Stat[] stats, int opType) { long count = 0; for (OpStat ops : getStatistics(stats, OpStat.class)) if (ops.getOp() == opType) count += ops.getCount(); return count; } /** Adds up instance counts across all entry types. */ private long getInstanceCount(Stat[] stats) { long count = 0; for (InstanceCount ops : getStatistics(stats, InstanceCount.class)) count += ops.getCount(); return count; } /** Gets size of a task queue with a particular task name */ private int getTaskQueue(Stat[] stats, String taskName) { for (TaskQueueStat ops : getStatistics(stats, TaskQueueStat.class)) if (taskName.equals(ops.getQueueName())) return ops.getQueueSize(); return 0; } } }