Mercurial > hg > blitz_condensed
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 } |