comparison 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
comparison
equal deleted inserted replaced
33:0b9265358617 34:6f68e94c1fb8
1 package org.dancres.blitz.tools;
2
3 import java.io.PrintStream;
4 import java.rmi.RemoteException;
5 import java.util.ArrayList;
6 import java.util.Collection;
7 import java.util.Formatter;
8
9 import org.dancres.blitz.remote.StatsAdmin;
10 import org.dancres.blitz.stats.BlockingOpsStat;
11 import org.dancres.blitz.stats.EventQueueStat;
12 import org.dancres.blitz.stats.IOStat;
13 import org.dancres.blitz.stats.InstanceCount;
14 import org.dancres.blitz.stats.MemoryStat;
15 import org.dancres.blitz.stats.MissedOpsStat;
16 import org.dancres.blitz.stats.OpStat;
17 import org.dancres.blitz.stats.Stat;
18 import org.dancres.blitz.stats.TaskQueueStat;
19 import org.dancres.blitz.stats.ThreadStat;
20 import org.dancres.blitz.stats.TxnStat;
21
22 /**
23 <p>CondensedStats accepts a spacename as an argument and a loop time. It
24 then regularly prints a condensed view of some important space stats every
25 loop time seconds. Specifying a loop time of 0 will cause MonitorStats to
26 dump stats once and exit.</p>
27
28 <p>Typical usage:
29
30 <pre>
31 java -Xmx256m -Djava.security.policy=config/policy.all
32 -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
33 org.dancres.blitz.tools.CondensedStats dancres 20
34 </pre>
35
36 @see org.dancres.blitz.remote.BlitzAdmin
37 */
38 public class CondensedStats extends MonitorStats {
39 public static void main(String args[]) {
40 new CondensedStats().startup(args);
41 }
42
43 @Override
44 Runnable getWatcher(StatsAdmin anAdmin, long aTimeout)
45 {
46 return new CondensedWatcher(anAdmin, aTimeout);
47 }
48
49 /**
50 * Provides a vmstat-style one line repeating summary of Blitz statistics.
51 * Includes operation counts, active txns/ops, listeners and queue stats,
52 * writer I/O and VM stats.
53 */
54 static class CondensedWatcher implements Runnable {
55 private StatsAdmin theAdmin;
56 private long theTimeout;
57 private Stat[] theLastStats;
58
59 CondensedWatcher(StatsAdmin anAdmin, long aTimeout) {
60 theAdmin = anAdmin;
61 theTimeout = aTimeout;
62 }
63
64 public void run() {
65 boolean run = true;
66 while (run) {
67 try {
68 // if timeout is 0, run once over a 1 second period
69 if (theTimeout == 0) {
70 run = false;
71 theTimeout = 1000;
72 }
73
74 printHeader(System.out);
75
76 theLastStats = theAdmin.getStats();
77
78 for (int i = 0;; i++) {
79 Thread.sleep(theTimeout);
80
81 print(System.out, (int)theTimeout / 1000);
82 if ((i + 1) % 48 == 0)
83 printHeader(System.out);
84 }
85 } catch (Exception anE) {
86 System.err.println(anE);
87 anE.printStackTrace();
88 }
89 }
90 }
91
92 public void printHeader(PrintStream out) {
93 out.println("-----ops---- " +
94 " missed " +
95 "obj " +
96 "---active-- " +
97 "listeners " +
98 "---queues-- " +
99 "------io----- " +
100 "-----vm-----");
101
102 out.println(" r t w " +
103 " r t " +
104 "+/- " +
105 "txn r t " +
106 " tr pt " +
107 "evt rem oth " +
108 " i/o qsz thr " +
109 "thrd mem max");
110 }
111
112 public void print(PrintStream out, int interval) throws RemoteException {
113 Stat[] last = theLastStats;
114 Stat[] stats = theAdmin.getStats();
115
116 // Operation count since last iteration
117 long opReads = getOpCount(stats, OpStat.READS) -
118 getOpCount(last, OpStat.READS);
119 long opTakes = getOpCount(stats, OpStat.TAKES) -
120 getOpCount(last, OpStat.TAKES);
121 long opWrites = (getOpCount(stats, OpStat.WRITES) -
122 getOpCount(last, OpStat.WRITES)) / interval;
123
124 // Missed operations, not available until first operation
125 long missReads = 0, missTakes = 0;
126 MissedOpsStat missedStat = getStatistic(stats, MissedOpsStat.class);
127 MissedOpsStat missedLast = getStatistic(stats, MissedOpsStat.class);
128
129 if (missedStat != null && missedLast != null) {
130 missReads = (missedStat.getMissedReads() - missedLast.getMissedReads())
131 / interval;
132 missTakes = (missedStat.getMissedTakes() - missedLast.getMissedTakes())
133 / interval;
134 }
135
136 // Change op counts to include misses
137 opReads = (opReads + missReads) / interval;
138 opTakes = (opTakes + missTakes) / interval;
139
140 // Overall instance count
141 long instances = (getInstanceCount(stats) - getInstanceCount(last))
142 / interval;
143
144 // Active operations/txns
145 int activeTxn = getStatistic(stats, TxnStat.class).getActiveTxnCount();
146
147 // Not available until after first space operation
148 int activeRead = 0, activeTake = 0;
149 BlockingOpsStat blockedOps = getStatistic(stats, BlockingOpsStat.class);
150 if (blockedOps != null) {
151 activeRead = blockedOps.getReaders();
152 activeTake = blockedOps.getTakers();
153 }
154
155 // Notify listeners
156 int listenTrans = getStatistic(stats, EventQueueStat.class).getTransientCount();
157 int listenPers = getStatistic(stats, EventQueueStat.class).getPersistentCount();
158
159 // Queues, internal notify queue, remote notify queue and other tasks
160 int queueEvents = getTaskQueue(stats, "Events");
161 int queueRemote = getTaskQueue(stats, "RemoteEvent");
162 int queueOther = getTaskQueue(stats, "DefaultTask");
163
164 // Writer I/O if persistent storage model in use
165 double ioRatio = 0;
166 int ioQueueSize = 0, ioThrottle = 0;
167
168 IOStat myIoStat = getStatistic(stats, IOStat.class);
169 if (myIoStat != null) {
170 ioRatio = myIoStat.getInOutRatio();
171 ioQueueSize = getStatistic(stats, IOStat.class).getQueueSize();
172 ioThrottle = (getStatistic(stats, IOStat.class).getThrottleCount() -
173 getStatistic(last, IOStat.class).getThrottleCount())
174 / interval;
175 }
176
177 // Virtual machine
178 int vmThreads = getStatistic(stats, ThreadStat.class).getThreadCount();
179
180 double vmMemory = getStatistic(stats, MemoryStat.class).getCurrentMemory();
181 vmMemory = vmMemory / 1024 / 1024 / 1024;
182
183 double vmMaxMem = getStatistic(stats, MemoryStat.class).getMaxMemory();
184 vmMaxMem = vmMaxMem / 1024 / 1024 / 1024;
185
186 // r t w$ r w$ +/-$txn r t$ tr pt
187 String formatString = "%4d %3d %3d %4d %3d %5d %4d %3d %3d %5d %4d ";
188 // evt rem oth$i/o qsz thr$thrd mem max
189 formatString += "%4d %3d %3d %5.1f %4d %3d %5d %3.1f %3.1f";
190
191 String line = new Formatter().format(formatString,
192 opReads, opTakes, opWrites,
193 missReads, missTakes, instances,
194 activeTxn, activeRead, activeTake,
195 listenTrans, listenPers,
196 queueEvents, queueRemote, queueOther,
197 ioRatio, ioQueueSize, ioThrottle,
198 vmThreads, vmMemory, vmMaxMem).toString();
199
200 out.println(line);
201
202 theLastStats = stats;
203 }
204
205 private <T extends Stat> Collection<T> getStatistics(Stat[] allStats,
206 Class<T> statClazz) {
207 Collection<T> ret = new ArrayList<T>();
208 for (Stat stat : allStats)
209 if (statClazz.isInstance(stat))
210 ret.add(statClazz.cast(stat));
211
212 return ret;
213 }
214
215 private <T extends Stat> T getStatistic(Stat[] allStats,
216 Class<T> statClazz) {
217 Collection<T> subset = getStatistics(allStats, statClazz);
218 return (subset.isEmpty()) ? null : subset.iterator().next();
219 }
220
221 /** Adds up operations across all entry types.
222 * @param opType OpStat.TAKES/READS/WRITES
223 */
224 private long getOpCount(Stat[] stats, int opType) {
225 long count = 0;
226 for (OpStat ops : getStatistics(stats, OpStat.class))
227 if (ops.getOp() == opType)
228 count += ops.getCount();
229
230 return count;
231 }
232
233 /** Adds up instance counts across all entry types. */
234 private long getInstanceCount(Stat[] stats) {
235 long count = 0;
236 for (InstanceCount ops : getStatistics(stats, InstanceCount.class))
237 count += ops.getCount();
238
239 return count;
240 }
241
242 /** Gets size of a task queue with a particular task name */
243 private int getTaskQueue(Stat[] stats, String taskName) {
244 for (TaskQueueStat ops : getStatistics(stats, TaskQueueStat.class))
245 if (taskName.equals(ops.getQueueName()))
246 return ops.getQueueSize();
247
248 return 0;
249 }
250 }
251 }